mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-15 16:44:36 +02:00
8281122: [IR Framework] Cleanup IR matching code in preparation for JDK-8280378
Reviewed-by: thartmann, kvn
This commit is contained in:
parent
d0eb6fa220
commit
2da677793f
56 changed files with 2739 additions and 752 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
package compiler.lib.ir_framework;
|
package compiler.lib.ir_framework;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.driver.IRViolationException;
|
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
|
||||||
|
|
||||||
import java.lang.annotation.Repeatable;
|
import java.lang.annotation.Repeatable;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
|
@ -58,8 +58,8 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
* If the specified preconditions fail, then the framework does not apply the IR rule. These preconditions can be
|
* 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()}.
|
* set with {@link #applyIf()}, {@link #applyIfNot()}, {@link #applyIfAnd()}, or {@link #applyIfOr()}.
|
||||||
* <p>
|
* <p>
|
||||||
* Examples on how to write tests with IR rules can be found in {@link jdk.test.lib.hotspot.ir_framework.examples.IRExample}
|
* 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 jdk.test.lib.hotspot.ir_framework.tests.TestIRMatching}.
|
* and also as part of the internal testing in {@link ir_framework.tests.TestIRMatching}.
|
||||||
*
|
*
|
||||||
* @see Test
|
* @see Test
|
||||||
* @see IRNode
|
* @see IRNode
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
package compiler.lib.ir_framework;
|
package compiler.lib.ir_framework;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.driver.IRMatcher;
|
import compiler.lib.ir_framework.driver.irmatching.IRMatcher;
|
||||||
import compiler.lib.ir_framework.shared.*;
|
import compiler.lib.ir_framework.shared.*;
|
||||||
import jdk.test.lib.Platform;
|
import jdk.test.lib.Platform;
|
||||||
import sun.hotspot.WhiteBox;
|
import sun.hotspot.WhiteBox;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
package compiler.lib.ir_framework;
|
package compiler.lib.ir_framework;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.driver.*;
|
import compiler.lib.ir_framework.driver.*;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.IRMatcher;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
|
||||||
import compiler.lib.ir_framework.shared.*;
|
import compiler.lib.ir_framework.shared.*;
|
||||||
import compiler.lib.ir_framework.test.*;
|
import compiler.lib.ir_framework.test.*;
|
||||||
import jdk.test.lib.Platform;
|
import jdk.test.lib.Platform;
|
||||||
|
@ -603,11 +605,11 @@ public class TestFramework {
|
||||||
// Print stack trace otherwise
|
// Print stack trace otherwise
|
||||||
StringWriter errors = new StringWriter();
|
StringWriter errors = new StringWriter();
|
||||||
e.printStackTrace(new PrintWriter(errors));
|
e.printStackTrace(new PrintWriter(errors));
|
||||||
builder.append(errors.toString());
|
builder.append(errors);
|
||||||
}
|
}
|
||||||
builder.append(System.lineSeparator());
|
builder.append(System.lineSeparator());
|
||||||
}
|
}
|
||||||
System.err.println(builder.toString());
|
System.err.println(builder);
|
||||||
if (!VERBOSE && !REPORT_STDOUT && !TESTLIST && !EXCLUDELIST) {
|
if (!VERBOSE && !REPORT_STDOUT && !TESTLIST && !EXCLUDELIST) {
|
||||||
// Provide a hint to the user how to get additional output/debugging information.
|
// Provide a hint to the user how to get additional output/debugging information.
|
||||||
System.err.println(RERUN_HINT);
|
System.err.println(RERUN_HINT);
|
||||||
|
|
|
@ -1,504 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2021, 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.driver;
|
|
||||||
|
|
||||||
import compiler.lib.ir_framework.*;
|
|
||||||
import compiler.lib.ir_framework.shared.*;
|
|
||||||
import compiler.lib.ir_framework.test.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the hotspot pid file of the test VM to match all @IR rules.
|
|
||||||
*/
|
|
||||||
public class IRMatcher {
|
|
||||||
public static final String SAFEPOINT_WHILE_PRINTING_MESSAGE = "<!-- safepoint while printing -->";
|
|
||||||
|
|
||||||
private static final boolean PRINT_IR_ENCODING = Boolean.parseBoolean(System.getProperty("PrintIREncoding", "false"));
|
|
||||||
private static final Pattern IR_ENCODING_PATTERN =
|
|
||||||
Pattern.compile("(?<=" + IREncodingPrinter.START + "\r?\n)[\\s\\S]*(?=" + IREncodingPrinter.END + ")");
|
|
||||||
private static final Pattern COMPILE_ID_PATTERN = Pattern.compile("compile_id='(\\d+)'");
|
|
||||||
|
|
||||||
private final Map<String, IRMethod> compilations;
|
|
||||||
private final Class<?> testClass;
|
|
||||||
private final Map<Method, List<String>> fails;
|
|
||||||
private final Pattern compileIdPatternForTestClass;
|
|
||||||
private final String hotspotPidFileName;
|
|
||||||
private IRMethod irMethod; // Current IR method to which rules are applied
|
|
||||||
private Method method; // Current method to which rules are applied
|
|
||||||
private IR irAnno; // Current IR annotation that is processed.
|
|
||||||
private int irRuleIndex; // Current IR rule index;
|
|
||||||
|
|
||||||
public IRMatcher(String hotspotPidFileName, String irEncoding, Class<?> testClass) {
|
|
||||||
this.compilations = new HashMap<>();
|
|
||||||
this.fails = new HashMap<>();
|
|
||||||
this.testClass = testClass;
|
|
||||||
this.compileIdPatternForTestClass = Pattern.compile("compile_id='(\\d+)'.*" + Pattern.quote(testClass.getCanonicalName())
|
|
||||||
+ " (\\S+)");
|
|
||||||
this.hotspotPidFileName = hotspotPidFileName;
|
|
||||||
setupTestMethods(irEncoding);
|
|
||||||
if (TestFramework.VERBOSE || PRINT_IR_ENCODING) {
|
|
||||||
System.out.println("Read IR encoding from test VM:");
|
|
||||||
System.out.println(irEncoding);
|
|
||||||
}
|
|
||||||
if (!compilations.isEmpty()) {
|
|
||||||
parseHotspotPidFile();
|
|
||||||
applyRules();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up a map testname -> IRMethod (containing the PrintIdeal and PrintOptoAssembly output for testname).
|
|
||||||
*/
|
|
||||||
private void setupTestMethods(String irEncoding) {
|
|
||||||
Map<String, int[]> irRulesMap = parseIREncoding(irEncoding);
|
|
||||||
for (Method m : testClass.getDeclaredMethods()) {
|
|
||||||
method = m;
|
|
||||||
IR[] irAnnos = m.getAnnotationsByType(IR.class);
|
|
||||||
if (irAnnos.length > 0) {
|
|
||||||
// Validation of legal @IR attributes and placement of the annotation was already done in Test VM.
|
|
||||||
int[] ids = irRulesMap.get(m.getName());
|
|
||||||
TestFramework.check(ids != null, "Should find method name in validIrRulesMap for " + m);
|
|
||||||
TestFramework.check(ids.length > 0, "Did not find any rule indices for " + m);
|
|
||||||
TestFramework.check(ids[ids.length - 1] < irAnnos.length, "Invalid IR rule index found in validIrRulesMap for " + m);
|
|
||||||
if (ids[0] != IREncodingPrinter.NO_RULE_APPLIED) {
|
|
||||||
// If -1, than there was no matching IR rule for the given conditions.
|
|
||||||
compilations.put(m.getName(), new IRMethod(m, ids, irAnnos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the IR encoding emitted by the test VM to decide if an @IR rule must be checked for a method.
|
|
||||||
*/
|
|
||||||
private Map<String, int[]> parseIREncoding(String irEncoding) {
|
|
||||||
Map<String, int[]> irRulesMap = new HashMap<>();
|
|
||||||
Matcher matcher = IR_ENCODING_PATTERN.matcher(irEncoding);
|
|
||||||
TestFramework.check(matcher.find(), "Did not find IR encoding");
|
|
||||||
String[] lines = matcher.group(0).split("\\R");
|
|
||||||
|
|
||||||
// Skip first line containing information about the format only
|
|
||||||
for (int i = 1; i < lines.length; i++) {
|
|
||||||
String line = lines[i].trim();
|
|
||||||
String[] splitComma = line.split(",");
|
|
||||||
if (splitComma.length < 2) {
|
|
||||||
throw new TestFrameworkException("Invalid IR match rule encoding. No comma found: " + splitComma[0]);
|
|
||||||
}
|
|
||||||
String testName = splitComma[0];
|
|
||||||
int[] irRulesIdx = new int[splitComma.length - 1];
|
|
||||||
for (int j = 1; j < splitComma.length; j++) {
|
|
||||||
try {
|
|
||||||
irRulesIdx[j - 1] = Integer.parseInt(splitComma[j]);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new TestFrameworkException("Invalid IR match rule encoding. No number found: " + splitComma[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
irRulesMap.put(testName, irRulesIdx);
|
|
||||||
}
|
|
||||||
return irRulesMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the hotspot_pid*.log file from the test VM. Read the PrintIdeal and PrintOptoAssembly entries for all
|
|
||||||
* methods of the test class that need to be IR matched (according to IR encoding).
|
|
||||||
*/
|
|
||||||
private void parseHotspotPidFile() {
|
|
||||||
Map<Integer, String> compileIdMap = new HashMap<>();
|
|
||||||
try (var br = Files.newBufferedReader(Paths.get(hotspotPidFileName))) {
|
|
||||||
String line;
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
boolean append = false;
|
|
||||||
String currentMethod = "";
|
|
||||||
while ((line = br.readLine()) != null) {
|
|
||||||
if (append && line.startsWith("</")) {
|
|
||||||
flushOutput(line, builder, currentMethod);
|
|
||||||
append = false;
|
|
||||||
currentMethod = "";
|
|
||||||
continue;
|
|
||||||
} else if (append) {
|
|
||||||
appendLine(builder, line);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maybeTestEntry(line)) {
|
|
||||||
addTestMethodCompileId(compileIdMap, line);
|
|
||||||
} else if (isPrintIdealStart(line)) {
|
|
||||||
String methodName = getMethodName(compileIdMap, line);
|
|
||||||
if (methodName != null) {
|
|
||||||
currentMethod = methodName;
|
|
||||||
append = true; // Append all following lines until we hit the closing </ideal> tag.
|
|
||||||
}
|
|
||||||
} else if (isPrintOptoAssemblyStart(line)) {
|
|
||||||
String methodName = getMethodName(compileIdMap, line);
|
|
||||||
if (methodName != null) {
|
|
||||||
TestFramework.check(compilations.containsKey(methodName), "Must be second entry of " + methodName);
|
|
||||||
currentMethod = methodName;
|
|
||||||
append = true; // Append all following lines until we hit the closing </opto_assembly> tag.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new TestFrameworkException("Error while reading " + hotspotPidFileName, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the input to the IR method and reset the builder.
|
|
||||||
*/
|
|
||||||
private void flushOutput(String line, StringBuilder builder, String currentMethod) {
|
|
||||||
TestFramework.check(!currentMethod.isEmpty(), "current method must be set");
|
|
||||||
IRMethod irMethod = compilations.get(currentMethod);
|
|
||||||
if (line.startsWith("</i")) {
|
|
||||||
// PrintIdeal
|
|
||||||
irMethod.setIdealOutput(builder.toString());
|
|
||||||
} else {
|
|
||||||
// PrintOptoAssembly
|
|
||||||
irMethod.setOptoAssemblyOutput(builder.toString());
|
|
||||||
}
|
|
||||||
builder.setLength(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only consider non-osr (no "compile_kind") and compilations with C2 (no "level")
|
|
||||||
*/
|
|
||||||
private boolean maybeTestEntry(String line) {
|
|
||||||
return line.startsWith("<task_queued") && !line.contains("compile_kind='") && !line.contains("level='");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Need to escape XML special characters.
|
|
||||||
*/
|
|
||||||
private static void appendLine(StringBuilder builder, String line) {
|
|
||||||
if (line.contains("&")) {
|
|
||||||
line = line.replace("<", "<");
|
|
||||||
line = line.replace(">", ">");
|
|
||||||
line = line.replace(""", "\"");
|
|
||||||
line = line.replace("'", "'");
|
|
||||||
line = line.replace("&", "&");
|
|
||||||
}
|
|
||||||
builder.append(line).append(System.lineSeparator());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getCompileId(Matcher matcher) {
|
|
||||||
int compileId;
|
|
||||||
try {
|
|
||||||
compileId = Integer.parseInt(matcher.group(1));
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new TestRunException("Could not parse compile id", e);
|
|
||||||
}
|
|
||||||
return compileId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the compile id from this line if it belongs to a method that needs to be IR tested (part of test class
|
|
||||||
* and IR encoding from the test VM specifies that this method has @IR rules to be checked).
|
|
||||||
*/
|
|
||||||
private void addTestMethodCompileId(Map<Integer, String> compileIdMap, String line) {
|
|
||||||
Matcher matcher = compileIdPatternForTestClass.matcher(line);
|
|
||||||
if (matcher.find()) {
|
|
||||||
// Only care about test class entries. Might have non-class entries as well if user specified additional
|
|
||||||
// compile commands. Ignore these.
|
|
||||||
String methodName = matcher.group(2);
|
|
||||||
if (compilations.containsKey(methodName)) {
|
|
||||||
// We only care about methods that we are actually gonna IR match based on IR encoding.
|
|
||||||
int compileId = getCompileId(matcher);
|
|
||||||
TestRun.check(!methodName.isEmpty(), "method name cannot be empty");
|
|
||||||
compileIdMap.put(compileId, methodName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make sure that line does not contain compile_kind which is used for OSR compilations which we are not
|
|
||||||
* interested in.
|
|
||||||
*/
|
|
||||||
private static boolean isPrintIdealStart(String line) {
|
|
||||||
return line.startsWith("<ideal") && !line.contains("compile_kind='");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make sure that line does not contain compile_kind which is used for OSR compilations which we are not
|
|
||||||
* interested in.
|
|
||||||
*/
|
|
||||||
private static boolean isPrintOptoAssemblyStart(String line) {
|
|
||||||
return line.startsWith("<opto_assembly") && !line.contains("compile_kind='");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get method name for this line by looking up the compile id.
|
|
||||||
* Returns null if not an interesting method (i.e. from test class).
|
|
||||||
*/
|
|
||||||
private String getMethodName(Map<Integer, String> compileIdMap, String line) {
|
|
||||||
Matcher matcher = COMPILE_ID_PATTERN.matcher(line);
|
|
||||||
TestFramework.check(matcher.find(), "Is " + hotspotPidFileName + " corrupted?");
|
|
||||||
int compileId = getCompileId(matcher);
|
|
||||||
return compileIdMap.get(compileId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do an IR matching of all methods with appliable @IR rules fetched during parsing of the hotspot pid file.
|
|
||||||
*/
|
|
||||||
private void applyRules() {
|
|
||||||
compilations.values().forEach(this::applyRulesForMethod);
|
|
||||||
reportFailuresIfAny();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyRulesForMethod(IRMethod irMethod) {
|
|
||||||
this.irMethod = irMethod;
|
|
||||||
method = irMethod.getMethod();
|
|
||||||
String testOutput = irMethod.getOutput();
|
|
||||||
if (testOutput.isEmpty()) {
|
|
||||||
String msg = "Method was not compiled. Did you specify any compiler directives preventing a compilation or used a " +
|
|
||||||
"@Run method in STANDALONE mode? In the latter case, make sure to always trigger a C2 compilation " +
|
|
||||||
"by invoking the test enough times.";
|
|
||||||
fails.computeIfAbsent(method, k -> new ArrayList<>()).add(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TestFramework.VERBOSE) {
|
|
||||||
System.out.println("Output of " + method + ":");
|
|
||||||
System.out.println(testOutput);
|
|
||||||
}
|
|
||||||
Arrays.stream(irMethod.getRuleIds()).forEach(this::applyIRRule);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply a single @IR rule as part of a method.
|
|
||||||
*/
|
|
||||||
private void applyIRRule(int id) {
|
|
||||||
irAnno = irMethod.getIrAnno(id);
|
|
||||||
irRuleIndex = id;
|
|
||||||
StringBuilder failMsg = new StringBuilder();
|
|
||||||
applyFailOn(failMsg);
|
|
||||||
try {
|
|
||||||
applyCounts(failMsg);
|
|
||||||
} catch (TestFormatException e) {
|
|
||||||
// Logged. Continue to check other rules.
|
|
||||||
}
|
|
||||||
if (!failMsg.isEmpty()) {
|
|
||||||
failMsg.insert(0, "@IR rule " + (id + 1) + ": \"" + irAnno + "\"" + System.lineSeparator());
|
|
||||||
fails.computeIfAbsent(method, k -> new ArrayList<>()).add(failMsg.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the failOn regexes of the @IR rule.
|
|
||||||
*/
|
|
||||||
private void applyFailOn(StringBuilder failMsg) {
|
|
||||||
if (irAnno.failOn().length != 0) {
|
|
||||||
String failOnRegex = String.join("|", IRNode.mergeNodes(irAnno.failOn()));
|
|
||||||
Pattern pattern = Pattern.compile(failOnRegex);
|
|
||||||
Matcher matcher = pattern.matcher(irMethod.getOutput());
|
|
||||||
long matchCount = matcher.results().count();
|
|
||||||
if (matchCount > 0) {
|
|
||||||
addFailOnFailsForOutput(failMsg, pattern, matchCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A failOn regex failed. Apply all regexes again to log the exact regex which failed. The failure is later reported
|
|
||||||
* to the user.
|
|
||||||
*/
|
|
||||||
private void addFailOnFailsForOutput(StringBuilder failMsg, Pattern pattern, long matchCount) {
|
|
||||||
long idealCount = pattern.matcher(irMethod.getIdealOutput()).results().count();
|
|
||||||
long optoAssemblyCount = pattern.matcher(irMethod.getOptoAssemblyOutput()).results().count();
|
|
||||||
if (matchCount != idealCount + optoAssemblyCount || (idealCount != 0 && optoAssemblyCount != 0)) {
|
|
||||||
// Report with Ideal and Opto Assembly
|
|
||||||
addFailOnFailsForOutput(failMsg, irMethod.getOutput());
|
|
||||||
irMethod.needsAllOutput();
|
|
||||||
} else if (optoAssemblyCount == 0) {
|
|
||||||
// Report with Ideal only
|
|
||||||
addFailOnFailsForOutput(failMsg, irMethod.getIdealOutput());
|
|
||||||
irMethod.needsIdeal();
|
|
||||||
} else {
|
|
||||||
// Report with Opto Assembly only
|
|
||||||
addFailOnFailsForOutput(failMsg, irMethod.getOptoAssemblyOutput());
|
|
||||||
irMethod.needsOptoAssembly();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the regexes to the testOutput and log the failures.
|
|
||||||
*/
|
|
||||||
private void addFailOnFailsForOutput(StringBuilder failMsg, String testOutput) {
|
|
||||||
List<String> failOnNodes = IRNode.mergeNodes(irAnno.failOn());
|
|
||||||
Pattern pattern;
|
|
||||||
Matcher matcher;
|
|
||||||
failMsg.append("- failOn: Graph contains forbidden nodes:").append(System.lineSeparator());
|
|
||||||
int nodeId = 1;
|
|
||||||
for (String nodeRegex : failOnNodes) {
|
|
||||||
pattern = Pattern.compile(nodeRegex);
|
|
||||||
matcher = pattern.matcher(testOutput);
|
|
||||||
long matchCount = matcher.results().count();
|
|
||||||
if (matchCount > 0) {
|
|
||||||
matcher.reset();
|
|
||||||
failMsg.append(" Regex ").append(nodeId).append(": ").append(nodeRegex).append(System.lineSeparator());
|
|
||||||
failMsg.append(" Matched forbidden node").append(matchCount > 1 ? "s (" + matchCount + ")" : "")
|
|
||||||
.append(":").append(System.lineSeparator());
|
|
||||||
matcher.results().forEach(r -> failMsg.append(" ").append(r.group()).append(System.lineSeparator()));
|
|
||||||
}
|
|
||||||
nodeId++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the counts regexes of the @IR rule.
|
|
||||||
*/
|
|
||||||
private void applyCounts(StringBuilder failMsg) {
|
|
||||||
if (irAnno.counts().length != 0) {
|
|
||||||
boolean hasFails = false;
|
|
||||||
String testOutput = irMethod.getOutput();
|
|
||||||
int countsId = 1;
|
|
||||||
final List<String> nodesWithCount = IRNode.mergeNodes(irAnno.counts());
|
|
||||||
for (int i = 0; i < nodesWithCount.size(); i += 2) {
|
|
||||||
String node = nodesWithCount.get(i);
|
|
||||||
TestFormat.check(i + 1 < nodesWithCount.size(), "Missing count" + getPostfixErrorMsg(node));
|
|
||||||
String countString = nodesWithCount.get(i + 1);
|
|
||||||
long expectedCount;
|
|
||||||
ParsedComparator<Long> parsedComparator;
|
|
||||||
try {
|
|
||||||
parsedComparator = ParsedComparator.parseComparator(countString);
|
|
||||||
expectedCount = Long.parseLong(parsedComparator.getStrippedString());
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
TestFormat.fail("Provided invalid count \"" + countString + "\"" + getPostfixErrorMsg(node));
|
|
||||||
return;
|
|
||||||
} catch (CheckedTestFrameworkException e) {
|
|
||||||
TestFormat.fail("Invalid comparator \"" + e.getMessage() + "\" in \"" + countString + "\" for count" + getPostfixErrorMsg(node));
|
|
||||||
return;
|
|
||||||
} catch (IndexOutOfBoundsException e) {
|
|
||||||
TestFormat.fail("Provided empty value" + getPostfixErrorMsg(node));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
TestFormat.check(expectedCount >= 0,"Provided invalid negative count \"" + countString + "\"" + getPostfixErrorMsg(node));
|
|
||||||
|
|
||||||
Pattern pattern = Pattern.compile(node);
|
|
||||||
Matcher matcher = pattern.matcher(testOutput);
|
|
||||||
long actualCount = matcher.results().count();
|
|
||||||
if (!parsedComparator.getPredicate().test(actualCount, expectedCount)) {
|
|
||||||
if (!hasFails) {
|
|
||||||
failMsg.append("- counts: Graph contains wrong number of nodes:").append(System.lineSeparator());
|
|
||||||
hasFails = true;
|
|
||||||
}
|
|
||||||
addCountsFail(failMsg, node, pattern, expectedCount, actualCount, countsId);
|
|
||||||
}
|
|
||||||
countsId++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getPostfixErrorMsg(String node) {
|
|
||||||
return " for IR rule " + irRuleIndex + ", node \"" + node + "\" at " + method;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A counts regex failed. Apply all regexes again to log the exact regex which failed. The failure is later reported
|
|
||||||
* to the user.
|
|
||||||
*/
|
|
||||||
private void addCountsFail(StringBuilder failMsg, String node, Pattern pattern, long expectedCount, long actualCount, int countsId) {
|
|
||||||
failMsg.append(" Regex ").append(countsId).append(": ").append(node).append(System.lineSeparator());
|
|
||||||
failMsg.append(" Expected ").append(expectedCount).append(" but found ").append(actualCount);
|
|
||||||
|
|
||||||
if (actualCount > 0) {
|
|
||||||
Matcher matcher = pattern.matcher(irMethod.getOutput());
|
|
||||||
long idealCount = pattern.matcher(irMethod.getIdealOutput()).results().count();
|
|
||||||
long optoAssemblyCount = pattern.matcher(irMethod.getOptoAssemblyOutput()).results().count();
|
|
||||||
if (actualCount != idealCount + optoAssemblyCount || (idealCount != 0 && optoAssemblyCount != 0)) {
|
|
||||||
irMethod.needsAllOutput();
|
|
||||||
} else if (optoAssemblyCount == 0) {
|
|
||||||
irMethod.needsIdeal();
|
|
||||||
} else {
|
|
||||||
irMethod.needsOptoAssembly();
|
|
||||||
}
|
|
||||||
failMsg.append(" node").append(actualCount > 1 ? "s" : "").append(":").append(System.lineSeparator());
|
|
||||||
matcher.results().forEach(r -> failMsg.append(" ").append(r.group()).append(System.lineSeparator()));
|
|
||||||
} else {
|
|
||||||
irMethod.needsAllOutput();
|
|
||||||
failMsg.append(" nodes.").append(System.lineSeparator());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report all IR violations in a pretty format to the user. Depending on the failed regex, we only report
|
|
||||||
* PrintIdeal or PrintOptoAssembly if the match failed there. If there were failures that matched things
|
|
||||||
* in both outputs than the entire output is reported. Throws IRViolationException from which the compilation
|
|
||||||
* can be read and reported to the stdout separately. The exception message only includes the summary of the
|
|
||||||
* failures.
|
|
||||||
*/
|
|
||||||
private void reportFailuresIfAny() {
|
|
||||||
TestFormat.reportIfAnyFailures();
|
|
||||||
if (!fails.isEmpty()) {
|
|
||||||
StringBuilder failuresBuilder = new StringBuilder();
|
|
||||||
StringBuilder compilationsBuilder = new StringBuilder();
|
|
||||||
int failures = 0;
|
|
||||||
for (Map.Entry<Method, List<String>> entry : fails.entrySet()) {
|
|
||||||
Method method = entry.getKey();
|
|
||||||
compilationsBuilder.append(">>> Compilation of ").append(method).append(":").append(System.lineSeparator());
|
|
||||||
IRMethod irMethod = compilations.get(method.getName());
|
|
||||||
String output;
|
|
||||||
if (irMethod.usesIdeal() && irMethod.usesOptoAssembly()) {
|
|
||||||
output = irMethod.getOutput();
|
|
||||||
} else if (irMethod.usesIdeal()) {
|
|
||||||
output = irMethod.getIdealOutput();
|
|
||||||
} else if (irMethod.usesOptoAssembly()) {
|
|
||||||
output = irMethod.getOptoAssemblyOutput();
|
|
||||||
} else {
|
|
||||||
output = "<empty>";
|
|
||||||
}
|
|
||||||
compilationsBuilder.append(output).append(System.lineSeparator()).append(System.lineSeparator());
|
|
||||||
List<String> list = entry.getValue();
|
|
||||||
failuresBuilder.append("- Method \"").append(method).append("\":").append(System.lineSeparator());
|
|
||||||
failures += list.size();
|
|
||||||
list.forEach(s -> failuresBuilder.append(" * ")
|
|
||||||
.append(s.replace(System.lineSeparator(),
|
|
||||||
System.lineSeparator() + " ").trim())
|
|
||||||
.append(System.lineSeparator()));
|
|
||||||
failuresBuilder.append(System.lineSeparator());
|
|
||||||
}
|
|
||||||
failuresBuilder.insert(0, ("One or more @IR rules failed:" + System.lineSeparator()
|
|
||||||
+ System.lineSeparator() + "Failed IR Rules (" + failures + ")"
|
|
||||||
+ System.lineSeparator()) + "-----------------"
|
|
||||||
+ "-".repeat(String.valueOf(failures).length()) + System.lineSeparator());
|
|
||||||
failuresBuilder.append(">>> Check stdout for compilation output of the failed methods")
|
|
||||||
.append(System.lineSeparator()).append(System.lineSeparator());
|
|
||||||
|
|
||||||
// In some very rare cases, the VM output to regex match on contains "<!-- safepoint while printing -->"
|
|
||||||
// (emitted by ttyLocker::break_tty_for_safepoint) which might be the reason for a matching error.
|
|
||||||
// Do not throw an exception in this case (i.e. bailout).
|
|
||||||
String compilations = compilationsBuilder.toString();
|
|
||||||
if (!compilations.contains(SAFEPOINT_WHILE_PRINTING_MESSAGE)) {
|
|
||||||
throw new IRViolationException(failuresBuilder.toString(), compilations);
|
|
||||||
} else {
|
|
||||||
System.out.println("Found " + SAFEPOINT_WHILE_PRINTING_MESSAGE + ", bail out of IR matching");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -194,13 +194,13 @@ public class TestVMProcess {
|
||||||
if (!testListBuilder.isEmpty()) {
|
if (!testListBuilder.isEmpty()) {
|
||||||
System.out.println("Run flag defined test list");
|
System.out.println("Run flag defined test list");
|
||||||
System.out.println("--------------------------");
|
System.out.println("--------------------------");
|
||||||
System.out.println(testListBuilder.toString());
|
System.out.println(testListBuilder);
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
if (!messagesBuilder.isEmpty()) {
|
if (!messagesBuilder.isEmpty()) {
|
||||||
System.out.println("Messages from Test VM");
|
System.out.println("Messages from Test VM");
|
||||||
System.out.println("---------------------");
|
System.out.println("---------------------");
|
||||||
System.out.println(messagesBuilder.toString());
|
System.out.println(messagesBuilder);
|
||||||
}
|
}
|
||||||
irEncoding = nonStdOutBuilder.toString();
|
irEncoding = nonStdOutBuilder.toString();
|
||||||
} else {
|
} else {
|
||||||
|
@ -226,7 +226,7 @@ public class TestVMProcess {
|
||||||
*/
|
*/
|
||||||
private void throwTestVMException() {
|
private void throwTestVMException() {
|
||||||
String stdErr = oa.getStderr();
|
String stdErr = oa.getStderr();
|
||||||
if (stdErr.contains("TestFormat.reportIfAnyFailures")) {
|
if (stdErr.contains("TestFormat.throwIfAnyFailures")) {
|
||||||
Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)");
|
Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)");
|
||||||
Matcher matcher = pattern.matcher(stdErr);
|
Matcher matcher = pattern.matcher(stdErr);
|
||||||
TestFramework.check(matcher.find(), "Must find violation matches");
|
TestFramework.check(matcher.find(), "Must find violation matches");
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to build the compilation output of IR matching failures.
|
||||||
|
*
|
||||||
|
* @see IRMethodMatchResult
|
||||||
|
*/
|
||||||
|
class CompilationOutputBuilder {
|
||||||
|
|
||||||
|
public static String build(List<IRMethodMatchResult> results) {
|
||||||
|
StringBuilder compilationsBuilder = new StringBuilder();
|
||||||
|
for (IRMethodMatchResult result : results) {
|
||||||
|
if (result.fail()) {
|
||||||
|
compilationsBuilder.append(buildMatchedCompilationMessage(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return compilationsBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildMatchedCompilationMessage(IRMethodMatchResult result) {
|
||||||
|
return result.getMatchedCompilationOutput() + System.lineSeparator() + System.lineSeparator();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* 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.driver.irmatching;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.*;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchResult;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.parser.IRMethodParser;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class parses the hotspot_pid* file of the test VM to match all applicable @IR rules afterwards.
|
||||||
|
*/
|
||||||
|
public class IRMatcher {
|
||||||
|
public static final String SAFEPOINT_WHILE_PRINTING_MESSAGE = "<!-- safepoint while printing -->";
|
||||||
|
|
||||||
|
public IRMatcher(String hotspotPidFileName, String irEncoding, Class<?> testClass) {
|
||||||
|
IRMethodParser irMethodParser = new IRMethodParser(testClass);
|
||||||
|
Collection<IRMethod> irMethods = irMethodParser.parse(hotspotPidFileName, irEncoding);
|
||||||
|
if (irMethods != null) {
|
||||||
|
applyIRRules(irMethods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do an IR matching of all methods with applicable @IR rules prepared with by the {@link IRMethodParser}.
|
||||||
|
*/
|
||||||
|
private void applyIRRules(Collection<IRMethod> irMethods) {
|
||||||
|
List<IRMethodMatchResult> results = new ArrayList<>();
|
||||||
|
irMethods.forEach(irMethod -> applyIRRule(irMethod, results));
|
||||||
|
if (!results.isEmpty()) {
|
||||||
|
reportFailures(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyIRRule(IRMethod irMethod, List<IRMethodMatchResult> results) {
|
||||||
|
if (TestFramework.VERBOSE) {
|
||||||
|
printMethodOutput(irMethod);
|
||||||
|
}
|
||||||
|
IRMethodMatchResult result = irMethod.applyIRRules();
|
||||||
|
if (result.fail()) {
|
||||||
|
results.add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printMethodOutput(IRMethod irMethod) {
|
||||||
|
System.out.println("Output of " + irMethod.getOutput() + ":");
|
||||||
|
System.out.println(irMethod.getOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report all IR violations in a pretty format to the user. Depending on the failed regex, we only report
|
||||||
|
* PrintIdeal or PrintOptoAssembly if the match failed there. If there were failures that matched things
|
||||||
|
* in both outputs then the entire output is reported. Throws IRViolationException from which the compilation
|
||||||
|
* can be read and reported to the stdout separately. The exception message only includes the summary of the
|
||||||
|
* failures.
|
||||||
|
*/
|
||||||
|
private void reportFailures(List<IRMethodMatchResult> results) {
|
||||||
|
Collections.sort(results); // Alphabetically
|
||||||
|
throwIfNoSafepointWhilePrinting(IRMatcherFailureMessageBuilder.build(results),
|
||||||
|
CompilationOutputBuilder.build(results));
|
||||||
|
}
|
||||||
|
|
||||||
|
// In some very rare cases, the VM output to regex match on contains "<!-- safepoint while printing -->"
|
||||||
|
// (emitted by ttyLocker::break_tty_for_safepoint) which might be the reason for a matching error.
|
||||||
|
// Do not throw an exception in this case (i.e. bailout).
|
||||||
|
private void throwIfNoSafepointWhilePrinting(String failures, String compilations) {
|
||||||
|
if (!compilations.contains(SAFEPOINT_WHILE_PRINTING_MESSAGE)) {
|
||||||
|
throw new IRViolationException(failures, compilations);
|
||||||
|
} else {
|
||||||
|
System.out.println("Found " + SAFEPOINT_WHILE_PRINTING_MESSAGE + ", bail out of IR matching");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to build the failure message output of IR matching failures.
|
||||||
|
*
|
||||||
|
* @see IRMethodMatchResult
|
||||||
|
*/
|
||||||
|
class IRMatcherFailureMessageBuilder {
|
||||||
|
|
||||||
|
public static String build(List<IRMethodMatchResult> results) {
|
||||||
|
StringBuilder failuresBuilder = new StringBuilder();
|
||||||
|
failuresBuilder.append(buildHeaderMessage(results));
|
||||||
|
int failureNumber = 1;
|
||||||
|
for (IRMethodMatchResult irMethodResult : results) {
|
||||||
|
if (irMethodResult.fail()) {
|
||||||
|
failuresBuilder.append(buildIRMethodFailureMessage(failureNumber, irMethodResult));
|
||||||
|
failureNumber++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failuresBuilder.append(buildFooterMessage());
|
||||||
|
return failuresBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildHeaderMessage(List<IRMethodMatchResult> results) {
|
||||||
|
int failedIRRulesCount = getFailedIRRulesCount(results);
|
||||||
|
long failedMethodCount = getFailedMethodCount(results);
|
||||||
|
return "One or more @IR rules failed:" + System.lineSeparator() + System.lineSeparator()
|
||||||
|
+ "Failed IR Rules (" + failedIRRulesCount + ") of Methods (" + failedMethodCount + ")"
|
||||||
|
+ System.lineSeparator()
|
||||||
|
+ "-".repeat(32 + digitCount(failedIRRulesCount) + digitCount(failedMethodCount))
|
||||||
|
+ System.lineSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getFailedIRRulesCount(List<IRMethodMatchResult> results) {
|
||||||
|
return results.stream().map(IRMethodMatchResult::getFailedIRRuleCount).reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getFailedMethodCount(List<IRMethodMatchResult> results) {
|
||||||
|
return results.stream().filter(IRMethodMatchResult::fail).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int digitCount(long digit) {
|
||||||
|
return String.valueOf(digit).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildIRMethodFailureMessage(int failureNumber, IRMethodMatchResult result) {
|
||||||
|
return failureNumber + ")" + result.buildFailureMessage() + System.lineSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildFooterMessage() {
|
||||||
|
return ">>> Check stdout for compilation output of the failed methods" + System.lineSeparator() + System.lineSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package compiler.lib.ir_framework.driver;
|
package compiler.lib.ir_framework.driver.irmatching;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.IR;
|
import compiler.lib.ir_framework.IR;
|
||||||
import compiler.lib.ir_framework.Test;
|
import compiler.lib.ir_framework.Test;
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface used by all classes which represent a IR match result. A result should also provide a failure message
|
||||||
|
* in a pretty format to be used by the {@link IRMatcher}.
|
||||||
|
*/
|
||||||
|
public interface MatchResult {
|
||||||
|
/**
|
||||||
|
* Does this match result represent a failure?
|
||||||
|
*/
|
||||||
|
boolean fail();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a failure message in a pretty format to be used by the IR matching failure reporting.
|
||||||
|
*/
|
||||||
|
String buildFailureMessage();
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum to describe what kind of compilation output that was matched for a method during IR matching.
|
||||||
|
*
|
||||||
|
* @see IRRuleMatchResult
|
||||||
|
*/
|
||||||
|
public enum OutputMatch {
|
||||||
|
/**
|
||||||
|
* There was no compilation output. Should not happen and results in a failure.
|
||||||
|
*/
|
||||||
|
NONE,
|
||||||
|
/**
|
||||||
|
* Matched on PrintIdeal.
|
||||||
|
*/
|
||||||
|
IDEAL,
|
||||||
|
/**
|
||||||
|
* Matched on PrintOptoAssembly.
|
||||||
|
*/
|
||||||
|
OPTO_ASSEMBLY,
|
||||||
|
/**
|
||||||
|
* Matched on PrintIdeal and PrintOptoAssembly.
|
||||||
|
*/
|
||||||
|
BOTH
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irmethod;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class to build the failure message output for an IR method.
|
||||||
|
*
|
||||||
|
* @see IRMethodMatchResult
|
||||||
|
*/
|
||||||
|
abstract class FailureMessageBuilder {
|
||||||
|
protected final IRMethod irMethod;
|
||||||
|
|
||||||
|
public FailureMessageBuilder(IRMethod irMethod) {
|
||||||
|
this.irMethod = irMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public String build();
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -21,30 +21,34 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package compiler.lib.ir_framework.driver;
|
package compiler.lib.ir_framework.driver.irmatching.irmethod;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.IR;
|
import compiler.lib.ir_framework.IR;
|
||||||
|
import compiler.lib.ir_framework.TestFramework;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRule;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to store information about a method that needs to be IR matched.
|
* Helper class to store information about a method that needs to be IR matched.
|
||||||
*/
|
*/
|
||||||
class IRMethod {
|
public class IRMethod {
|
||||||
private final Method method;
|
private final Method method;
|
||||||
private final int[] ruleIds;
|
private final List<IRRule> irRules;
|
||||||
private final IR[] irAnnos;
|
|
||||||
private final StringBuilder outputBuilder;
|
private final StringBuilder outputBuilder;
|
||||||
private String output;
|
private String output;
|
||||||
private String idealOutput;
|
private String idealOutput;
|
||||||
private String optoAssemblyOutput;
|
private String optoAssemblyOutput;
|
||||||
private boolean needsIdeal;
|
|
||||||
private boolean needsOptoAssembly;
|
|
||||||
|
|
||||||
public IRMethod(Method method, int[] ruleIds, IR[] irAnnos) {
|
public IRMethod(Method method, int[] ruleIds, IR[] irAnnos) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.ruleIds = ruleIds;
|
this.irRules = new ArrayList<>();
|
||||||
this.irAnnos = irAnnos;
|
for (int i : ruleIds) {
|
||||||
|
irRules.add(new IRRule(this, i, irAnnos[i - 1]));
|
||||||
|
}
|
||||||
this.outputBuilder = new StringBuilder();
|
this.outputBuilder = new StringBuilder();
|
||||||
this.output = "";
|
this.output = "";
|
||||||
this.idealOutput = "";
|
this.idealOutput = "";
|
||||||
|
@ -55,13 +59,6 @@ class IRMethod {
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getRuleIds() {
|
|
||||||
return ruleIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IR getIrAnno(int idx) {
|
|
||||||
return irAnnos[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Ideal output comes always before the Opto Assembly output. We might parse multiple C2 compilations of this method.
|
* The Ideal output comes always before the Opto Assembly output. We might parse multiple C2 compilations of this method.
|
||||||
|
@ -94,24 +91,26 @@ class IRMethod {
|
||||||
return optoAssemblyOutput;
|
return optoAssemblyOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void needsAllOutput() {
|
/**
|
||||||
needsIdeal();
|
* Apply all IR rules of this IR method.
|
||||||
needsOptoAssembly();
|
*/
|
||||||
|
public IRMethodMatchResult applyIRRules() {
|
||||||
|
TestFramework.check(!irRules.isEmpty(), "IRMethod cannot be created if there are no IR rules to apply");
|
||||||
|
List<IRRuleMatchResult> results = new ArrayList<>();
|
||||||
|
if (!output.isEmpty()) {
|
||||||
|
return getNormalMatchResult(results);
|
||||||
|
} else {
|
||||||
|
return new MissingCompilationResult(this, irRules.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void needsIdeal() {
|
private NormalMatchResult getNormalMatchResult(List<IRRuleMatchResult> results) {
|
||||||
needsIdeal = true;
|
for (IRRule irRule : irRules) {
|
||||||
}
|
IRRuleMatchResult result = irRule.applyCheckAttribute();
|
||||||
|
if (result.fail()) {
|
||||||
public boolean usesIdeal() {
|
results.add(result);
|
||||||
return needsIdeal;
|
}
|
||||||
}
|
}
|
||||||
|
return new NormalMatchResult(this, results);
|
||||||
public void needsOptoAssembly() {
|
|
||||||
needsOptoAssembly = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean usesOptoAssembly() {
|
|
||||||
return needsOptoAssembly;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irmethod;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This base class represents an IR matching result of all IR rules of a method.
|
||||||
|
*
|
||||||
|
* @see IRRuleMatchResult
|
||||||
|
* @see IRMethod
|
||||||
|
*/
|
||||||
|
abstract public class IRMethodMatchResult implements Comparable<IRMethodMatchResult>, MatchResult {
|
||||||
|
protected final IRMethod irMethod;
|
||||||
|
|
||||||
|
IRMethodMatchResult(IRMethod irMethod) {
|
||||||
|
this.irMethod = irMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public String getMatchedCompilationOutput();
|
||||||
|
|
||||||
|
abstract public int getFailedIRRuleCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to sort the failed IR methods alphabetically.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compareTo(IRMethodMatchResult other) {
|
||||||
|
return this.irMethod.getMethod().getName().compareTo(other.irMethod.getMethod().getName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irmethod;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.OutputMatch;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
|
||||||
|
import compiler.lib.ir_framework.shared.TestFrameworkException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to build the compilation output for an IR method.
|
||||||
|
*
|
||||||
|
* @see IRMethodMatchResult
|
||||||
|
*/
|
||||||
|
class MatchedCompilationOutputBuilder {
|
||||||
|
private final IRMethod irMethod;
|
||||||
|
private final OutputMatch outputMatch;
|
||||||
|
|
||||||
|
public MatchedCompilationOutputBuilder(IRMethod irMethod, List<IRRuleMatchResult> irRulesMatchResults) {
|
||||||
|
this.irMethod = irMethod;
|
||||||
|
this.outputMatch = getOutputMatch(irRulesMatchResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OutputMatch getOutputMatch(List<IRRuleMatchResult> irRulesMatchResults) {
|
||||||
|
OutputMatch outputMatch;
|
||||||
|
if (allMatchesOn(irRulesMatchResults, OutputMatch.IDEAL)) {
|
||||||
|
outputMatch = OutputMatch.IDEAL;
|
||||||
|
} else if (allMatchesOn(irRulesMatchResults, OutputMatch.OPTO_ASSEMBLY)) {
|
||||||
|
outputMatch = OutputMatch.OPTO_ASSEMBLY;
|
||||||
|
} else {
|
||||||
|
outputMatch = OutputMatch.BOTH;
|
||||||
|
}
|
||||||
|
return outputMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean allMatchesOn(List<IRRuleMatchResult> irRulesMatchResults, OutputMatch outputMatch) {
|
||||||
|
return irRulesMatchResults.stream().allMatch(r -> r.getOutputMatch() == outputMatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String build() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append(getMethodLine());
|
||||||
|
switch (outputMatch) {
|
||||||
|
case IDEAL -> builder.append(irMethod.getIdealOutput());
|
||||||
|
case OPTO_ASSEMBLY -> builder.append(irMethod.getOptoAssemblyOutput());
|
||||||
|
case BOTH -> builder.append(irMethod.getOutput());
|
||||||
|
default -> throw new TestFrameworkException("found unexpected OutputMatch " + outputMatch.name());
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMethodLine() {
|
||||||
|
return ">>> Compilation of " + irMethod.getMethod() + ":" + System.lineSeparator();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irmethod;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to build the failure message output for an IR method with a missing compilation output.
|
||||||
|
*
|
||||||
|
* @see IRMethodMatchResult
|
||||||
|
*/
|
||||||
|
class MissingCompilationMessageBuilder extends FailureMessageBuilder {
|
||||||
|
|
||||||
|
public MissingCompilationMessageBuilder(IRMethod irMethod) {
|
||||||
|
super(irMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String build() {
|
||||||
|
return getMethodLine() + getMissingCompilationMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMissingCompilationMessage() {
|
||||||
|
return " * Method was not compiled. Did you specify any compiler directives preventing a compilation "
|
||||||
|
+ "or used a @Run method in STANDALONE mode? In the latter case, make sure to always trigger a C2 "
|
||||||
|
+ "compilation by " + "invoking the test enough times.";
|
||||||
|
}
|
||||||
|
private String getMethodLine() {
|
||||||
|
return " Method \"" + irMethod.getMethod() + "\":" + System.lineSeparator();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irmethod;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an IR matching result where the compilation output was empty.
|
||||||
|
*
|
||||||
|
* @see IRRuleMatchResult
|
||||||
|
* @see IRMethod
|
||||||
|
*/
|
||||||
|
public class MissingCompilationResult extends IRMethodMatchResult {
|
||||||
|
private final int failedIRRules;
|
||||||
|
private final MissingCompilationMessageBuilder failureMessageBuilder;
|
||||||
|
|
||||||
|
MissingCompilationResult(IRMethod irMethod, int failedIRRules) {
|
||||||
|
super(irMethod);
|
||||||
|
this.failedIRRules = failedIRRules;
|
||||||
|
this.failureMessageBuilder = new MissingCompilationMessageBuilder(irMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fail() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMatchedCompilationOutput() {
|
||||||
|
return "<empty>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildFailureMessage() {
|
||||||
|
return failureMessageBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMethodLine() {
|
||||||
|
return " Method \"" + irMethod.getMethod() + "\":" + System.lineSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFailedIRRuleCount() {
|
||||||
|
return failedIRRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irmethod;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to build the failure message output for an IR method for failed IR rules.
|
||||||
|
*
|
||||||
|
* @see IRMethodMatchResult
|
||||||
|
*/
|
||||||
|
class NormalFailureMessageBuilder extends FailureMessageBuilder {
|
||||||
|
private final List<IRRuleMatchResult> irRulesMatchResults;
|
||||||
|
|
||||||
|
public NormalFailureMessageBuilder(IRMethod irMethod, List<IRRuleMatchResult> irRulesMatchResults) {
|
||||||
|
super(irMethod);
|
||||||
|
this.irRulesMatchResults = irRulesMatchResults.stream()
|
||||||
|
.filter(IRRuleMatchResult::fail)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String build() {
|
||||||
|
return getMethodLine() + getIRRulesFailureMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMethodLine() {
|
||||||
|
int failures = irRulesMatchResults.size();
|
||||||
|
return " Method \"" + irMethod.getMethod() + "\" - [Failed IR rules: " + failures + "]:"
|
||||||
|
+ System.lineSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getIRRulesFailureMessage() {
|
||||||
|
StringBuilder failMsg = new StringBuilder();
|
||||||
|
for (IRRuleMatchResult irRuleResult : irRulesMatchResults) {
|
||||||
|
failMsg.append(irRuleResult.buildFailureMessage());
|
||||||
|
}
|
||||||
|
return failMsg.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irmethod;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a normal IR matching result of all IR rules of a method.
|
||||||
|
*
|
||||||
|
* @see IRRuleMatchResult
|
||||||
|
* @see IRMethod
|
||||||
|
*/
|
||||||
|
class NormalMatchResult extends IRMethodMatchResult {
|
||||||
|
private final List<IRRuleMatchResult> irRulesMatchResults;
|
||||||
|
private final NormalFailureMessageBuilder failureMessageBuilder;
|
||||||
|
private final MatchedCompilationOutputBuilder matchedCompilationOutputBuilder;
|
||||||
|
|
||||||
|
NormalMatchResult(IRMethod irMethod, List<IRRuleMatchResult> irRulesMatchResults) {
|
||||||
|
super(irMethod);
|
||||||
|
this.irRulesMatchResults = irRulesMatchResults;
|
||||||
|
this.failureMessageBuilder = new NormalFailureMessageBuilder(irMethod, irRulesMatchResults);
|
||||||
|
this.matchedCompilationOutputBuilder = new MatchedCompilationOutputBuilder(irMethod, irRulesMatchResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fail() {
|
||||||
|
return !irRulesMatchResults.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMatchedCompilationOutput() {
|
||||||
|
return matchedCompilationOutputBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildFailureMessage() {
|
||||||
|
return failureMessageBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFailedIRRuleCount() {
|
||||||
|
return irRulesMatchResults.size();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.IR;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class representing a check attribute of an IR rule.
|
||||||
|
*
|
||||||
|
* @see IR
|
||||||
|
*/
|
||||||
|
abstract class CheckAttribute {
|
||||||
|
|
||||||
|
abstract public CheckAttributeMatchResult apply(String compilation);
|
||||||
|
|
||||||
|
protected List<String> getMatchedNodes(Matcher m) {
|
||||||
|
List<String> matches = new ArrayList<>();
|
||||||
|
do {
|
||||||
|
matches.add(m.group());
|
||||||
|
} while (m.find());
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.IR;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class representing a result of an applied check attribute of an IR rule.
|
||||||
|
*
|
||||||
|
* @see IR
|
||||||
|
*/
|
||||||
|
abstract class CheckAttributeMatchResult implements MatchResult {
|
||||||
|
protected List<RegexFailure> regexFailures = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fail() {
|
||||||
|
return regexFailures != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMatchesCount() {
|
||||||
|
if (fail()) {
|
||||||
|
return regexFailures.stream().map(RegexFailure::getMatchesCount).reduce(0, Integer::sum);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String collectRegexFailureMessages() {
|
||||||
|
StringBuilder failMsg = new StringBuilder();
|
||||||
|
for (RegexFailure regexFailure : regexFailures) {
|
||||||
|
failMsg.append(regexFailure.buildFailureMessage());
|
||||||
|
}
|
||||||
|
return failMsg.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.IR;
|
||||||
|
import compiler.lib.ir_framework.shared.Comparison;
|
||||||
|
import compiler.lib.ir_framework.shared.ComparisonConstraintParser;
|
||||||
|
import compiler.lib.ir_framework.shared.TestFormat;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing a counts attribute of an IR rule.
|
||||||
|
*
|
||||||
|
* @see IR#counts()
|
||||||
|
*/
|
||||||
|
class Counts extends CheckAttribute {
|
||||||
|
public List<Constraint> constraints;
|
||||||
|
|
||||||
|
private Counts(List<Constraint> constraints) {
|
||||||
|
this.constraints = constraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Counts create(List<String> nodesWithCountConstraint, IRRule irRule) {
|
||||||
|
List<Constraint> constraints = new ArrayList<>();
|
||||||
|
int nodeId = 1;
|
||||||
|
for (int i = 0; i < nodesWithCountConstraint.size(); i += 2, nodeId++) {
|
||||||
|
String node = nodesWithCountConstraint.get(i);
|
||||||
|
TestFormat.check(i + 1 < nodesWithCountConstraint.size(),
|
||||||
|
"Missing count " + getPostfixErrorMsg(irRule, node));
|
||||||
|
String countConstraint = nodesWithCountConstraint.get(i + 1);
|
||||||
|
Comparison<Long> comparison = parseComparison(irRule, node, countConstraint);
|
||||||
|
constraints.add(new Constraint(node, comparison, nodeId));
|
||||||
|
}
|
||||||
|
return new Counts(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getPostfixErrorMsg(IRRule irRule, String node) {
|
||||||
|
return "for IR rule " + irRule.getRuleId() + ", node \"" + node + "\" at " + irRule.getMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Comparison<Long> parseComparison(IRRule irRule, String node, String constraint) {
|
||||||
|
String postfixErrorMsg = "in count constraint " + getPostfixErrorMsg(irRule, node);
|
||||||
|
return ComparisonConstraintParser.parse(constraint, Long::parseLong, postfixErrorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckAttributeMatchResult apply(String compilation) {
|
||||||
|
CountsMatchResult result = new CountsMatchResult();
|
||||||
|
checkConstraints(result, compilation);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkConstraints(CountsMatchResult result, String compilation) {
|
||||||
|
for (Constraint constraint : constraints) {
|
||||||
|
checkConstraint(result, compilation, constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkConstraint(CountsMatchResult result, String compilation, Constraint constraint) {
|
||||||
|
long foundCount = getFoundCount(compilation, constraint);
|
||||||
|
Comparison<Long> comparison = constraint.comparison;
|
||||||
|
if (!comparison.compare(foundCount)) {
|
||||||
|
result.addFailure(createRegexFailure(compilation, constraint, foundCount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getFoundCount(String compilation, Constraint constraint) {
|
||||||
|
Pattern pattern = Pattern.compile(constraint.nodeRegex);
|
||||||
|
Matcher matcher = pattern.matcher(compilation);
|
||||||
|
return matcher.results().count();
|
||||||
|
}
|
||||||
|
|
||||||
|
private CountsRegexFailure createRegexFailure(String compilation, Constraint constraint, long foundCount) {
|
||||||
|
Pattern p = Pattern.compile(constraint.nodeRegex);
|
||||||
|
Matcher m = p.matcher(compilation);
|
||||||
|
List<String> matches;
|
||||||
|
if (m.find()) {
|
||||||
|
matches = getMatchedNodes(m);
|
||||||
|
} else {
|
||||||
|
matches = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return new CountsRegexFailure(constraint.nodeRegex, constraint.nodeId, foundCount, constraint.comparison, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Constraint {
|
||||||
|
final String nodeRegex;
|
||||||
|
final Comparison<Long> comparison;
|
||||||
|
private final int nodeId;
|
||||||
|
|
||||||
|
Constraint(String nodeRegex, Comparison<Long> comparison, int nodeId) {
|
||||||
|
this.nodeRegex = nodeRegex;
|
||||||
|
this.comparison = comparison;
|
||||||
|
this.nodeId = nodeId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.IR;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing a result of an applied counts attribute of an IR rule.
|
||||||
|
*
|
||||||
|
* @see IR#counts()
|
||||||
|
*/
|
||||||
|
class CountsMatchResult extends CheckAttributeMatchResult {
|
||||||
|
|
||||||
|
public void addFailure(RegexFailure regexFailure) {
|
||||||
|
if (regexFailures == null) {
|
||||||
|
regexFailures = new ArrayList<>();
|
||||||
|
}
|
||||||
|
regexFailures.add(regexFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildFailureMessage() {
|
||||||
|
return " - counts: Graph contains wrong number of nodes:" + System.lineSeparator()
|
||||||
|
+ collectRegexFailureMessages();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.shared.Comparison;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an IR matching failure of a regex of a counts attribute of an IR rule.
|
||||||
|
*
|
||||||
|
* @see Counts
|
||||||
|
*/
|
||||||
|
class CountsRegexFailure extends RegexFailure {
|
||||||
|
String failedComparison;
|
||||||
|
|
||||||
|
public CountsRegexFailure(String nodeRegex, int nodeId, long foundValue, Comparison<Long> comparison, List<String> matches) {
|
||||||
|
super(nodeRegex, nodeId, matches);
|
||||||
|
this.failedComparison = "[found] " + foundValue + " " + comparison.getComparator() + " "
|
||||||
|
+ comparison.getGivenValue() + " [given]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildFailureMessage() {
|
||||||
|
return getRegexLine()
|
||||||
|
+ getFailedComparison()
|
||||||
|
+ getMatchedNodesBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFailedComparison() {
|
||||||
|
return " - Failed comparison: " + failedComparison + System.lineSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getMatchedNodesBlock() {
|
||||||
|
if (matches.isEmpty()) {
|
||||||
|
return getEmptyNodeMatchesLine();
|
||||||
|
} else {
|
||||||
|
return super.getMatchedNodesBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getEmptyNodeMatchesLine() {
|
||||||
|
return getMatchedNodesWhiteSpace() + "- No nodes matched!" + System.lineSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getMatchedPrefix() {
|
||||||
|
return "Matched";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.IR;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing a failOn attribute of an IR rule.
|
||||||
|
*
|
||||||
|
* @see IR#failOn()
|
||||||
|
*/
|
||||||
|
class FailOn extends CheckAttribute {
|
||||||
|
private final Pattern quickPattern;
|
||||||
|
private final List<String> nodes;
|
||||||
|
|
||||||
|
public FailOn(List<String> nodes) {
|
||||||
|
this.nodes = nodes;
|
||||||
|
this.quickPattern = Pattern.compile(String.join("|", nodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckAttributeMatchResult apply(String compilation) {
|
||||||
|
FailOnMatchResult result = new FailOnMatchResult();
|
||||||
|
Matcher matcher = quickPattern.matcher(compilation);
|
||||||
|
if (matcher.find()) {
|
||||||
|
result.setFailures(createFailOnFailures(compilation));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<RegexFailure> createFailOnFailures(String compilation) {
|
||||||
|
List<RegexFailure> regexFailures = new ArrayList<>();
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
checkNode(regexFailures, compilation, nodes.get(i), i + 1);
|
||||||
|
}
|
||||||
|
return regexFailures;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkNode(List<RegexFailure> regexFailures, String compilation, String node, int nodeId) {
|
||||||
|
Pattern p = Pattern.compile(node);
|
||||||
|
Matcher m = p.matcher(compilation);
|
||||||
|
if (m.find()) {
|
||||||
|
List<String> matches = getMatchedNodes(m);
|
||||||
|
regexFailures.add(new FailOnRegexFailure(node, nodeId, matches));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.IR;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing a result of an applied failOn attribute of an IR rule.
|
||||||
|
*
|
||||||
|
* @see IR#failOn()
|
||||||
|
*/
|
||||||
|
class FailOnMatchResult extends CheckAttributeMatchResult {
|
||||||
|
public void setFailures(List<RegexFailure> regexFailures) {
|
||||||
|
this.regexFailures = regexFailures;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildFailureMessage() {
|
||||||
|
return " - failOn: Graph contains forbidden nodes:" + System.lineSeparator()
|
||||||
|
+ collectRegexFailureMessages();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an IR matching failure of a regex of a failOn attribute of an IR rule.
|
||||||
|
*
|
||||||
|
* @see FailOn
|
||||||
|
*/
|
||||||
|
class FailOnRegexFailure extends RegexFailure {
|
||||||
|
|
||||||
|
public FailOnRegexFailure(String nodeRegex, int nodeId, List<String> matches) {
|
||||||
|
super(nodeRegex, nodeId, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildFailureMessage() {
|
||||||
|
return getRegexLine()
|
||||||
|
+ getMatchedNodesBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getMatchedPrefix() {
|
||||||
|
return "Matched forbidden";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.IR;
|
||||||
|
import compiler.lib.ir_framework.IRNode;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.OutputMatch;
|
||||||
|
import compiler.lib.ir_framework.shared.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class IRRule {
|
||||||
|
private final IRMethod irMethod;
|
||||||
|
private final int ruleId;
|
||||||
|
private final IR irAnno;
|
||||||
|
private final FailOn failOn;
|
||||||
|
private final Counts counts;
|
||||||
|
|
||||||
|
public IRRule(IRMethod irMethod, int ruleId, IR irAnno) {
|
||||||
|
this.irMethod = irMethod;
|
||||||
|
this.ruleId = ruleId;
|
||||||
|
this.irAnno = irAnno;
|
||||||
|
this.failOn = initFailOn(irAnno);
|
||||||
|
this.counts = initCounts(irAnno);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Counts initCounts(IR irAnno) {
|
||||||
|
String[] countsConstraints = irAnno.counts();
|
||||||
|
if (countsConstraints.length != 0) {
|
||||||
|
try {
|
||||||
|
return Counts.create(IRNode.mergeNodes(countsConstraints), this);
|
||||||
|
} catch (TestFormatException e) {
|
||||||
|
// Logged and reported later. Continue.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FailOn initFailOn(IR irAnno) {
|
||||||
|
String[] failOnNodes = irAnno.failOn();
|
||||||
|
if (failOnNodes.length != 0) {
|
||||||
|
return new FailOn(IRNode.mergeNodes(failOnNodes));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRuleId() {
|
||||||
|
return ruleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IR getIRAnno() {
|
||||||
|
return irAnno;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Method getMethod() {
|
||||||
|
return irMethod.getMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply this IR rule by checking any failOn and counts attributes.
|
||||||
|
*/
|
||||||
|
public IRRuleMatchResult applyCheckAttribute() {
|
||||||
|
IRRuleMatchResult result = new IRRuleMatchResult(this);
|
||||||
|
if (failOn != null) {
|
||||||
|
applyCheckAttribute(failOn, result, result::setFailOnFailures);
|
||||||
|
}
|
||||||
|
if (counts != null) {
|
||||||
|
applyCheckAttribute(counts, result, result::setCountsFailures);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyCheckAttribute(CheckAttribute checkAttribute, IRRuleMatchResult result,
|
||||||
|
Consumer<CheckAttributeMatchResult> setFailures) {
|
||||||
|
CheckAttributeMatchResult checkAttributeResult = checkAttribute.apply(irMethod.getOutput());
|
||||||
|
if (checkAttributeResult.fail()) {
|
||||||
|
setFailures.accept(checkAttributeResult);
|
||||||
|
result.updateOutputMatch(getOutputMatch(checkAttribute, checkAttributeResult));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine how the output was matched by reapplying the check attribute for the PrintIdeal and PrintOptoAssembly
|
||||||
|
* output separately.
|
||||||
|
*/
|
||||||
|
private OutputMatch getOutputMatch(CheckAttribute checkAttribute, CheckAttributeMatchResult checkAttributeResult) {
|
||||||
|
int totalMatches = checkAttributeResult.getMatchesCount();
|
||||||
|
int idealFailuresCount = getMatchesCount(checkAttribute, irMethod.getIdealOutput());
|
||||||
|
int optoAssemblyFailuresCount = getMatchesCount(checkAttribute, irMethod.getOptoAssemblyOutput());
|
||||||
|
return findOutputMatch(totalMatches, idealFailuresCount, optoAssemblyFailuresCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getMatchesCount(CheckAttribute checkAttribute, String compilation) {
|
||||||
|
CheckAttributeMatchResult result = checkAttribute.apply(compilation);
|
||||||
|
return result.getMatchesCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare different counts to find out, on what output a failure was matched.
|
||||||
|
*/
|
||||||
|
private OutputMatch findOutputMatch(int totalMatches, int idealFailuresCount, int optoAssemblyFailuresCount) {
|
||||||
|
if (totalMatches == 0
|
||||||
|
|| someRegexMatchOnlyEntireOutput(totalMatches, idealFailuresCount, optoAssemblyFailuresCount)
|
||||||
|
|| anyMatchOnIdealAndOptoAssembly(idealFailuresCount, optoAssemblyFailuresCount)) {
|
||||||
|
return OutputMatch.BOTH;
|
||||||
|
} else if (optoAssemblyFailuresCount == 0) {
|
||||||
|
return OutputMatch.IDEAL;
|
||||||
|
} else {
|
||||||
|
return OutputMatch.OPTO_ASSEMBLY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do we have a regex that is only matched on the entire ideal + opto assembly output?
|
||||||
|
*/
|
||||||
|
private boolean someRegexMatchOnlyEntireOutput(int totalCount, int idealFailuresCount, int optoAssemblyFailuresCount) {
|
||||||
|
return totalCount != idealFailuresCount + optoAssemblyFailuresCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do we have a match on ideal and opto assembly for this rule?
|
||||||
|
*/
|
||||||
|
private boolean anyMatchOnIdealAndOptoAssembly(int idealFailuresCount, int optoAssemblyFailuresCount) {
|
||||||
|
return idealFailuresCount > 0 && optoAssemblyFailuresCount > 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.TestFramework;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.OutputMatch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an IR matching result of an IR rule.
|
||||||
|
*
|
||||||
|
* @see CheckAttributeMatchResult
|
||||||
|
* @see IRRule
|
||||||
|
*/
|
||||||
|
public class IRRuleMatchResult implements MatchResult {
|
||||||
|
private final IRRule irRule;
|
||||||
|
private CheckAttributeMatchResult failOnFailures = null;
|
||||||
|
private CheckAttributeMatchResult countsFailures = null;
|
||||||
|
private OutputMatch outputMatch;
|
||||||
|
|
||||||
|
public IRRuleMatchResult(IRRule irRule) {
|
||||||
|
this.irRule = irRule;
|
||||||
|
this.outputMatch = OutputMatch.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasFailOnFailures() {
|
||||||
|
return failOnFailures != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFailOnFailures(CheckAttributeMatchResult failOnFailures) {
|
||||||
|
this.failOnFailures = failOnFailures;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasCountsFailures() {
|
||||||
|
return countsFailures != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCountsFailures(CheckAttributeMatchResult countsFailures) {
|
||||||
|
this.countsFailures = countsFailures;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OutputMatch getOutputMatch() {
|
||||||
|
return outputMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fail() {
|
||||||
|
return failOnFailures != null || countsFailures != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateOutputMatch(OutputMatch newOutputMatch) {
|
||||||
|
TestFramework.check(newOutputMatch != OutputMatch.NONE, "must be valid state");
|
||||||
|
switch (outputMatch) {
|
||||||
|
case NONE -> outputMatch = newOutputMatch;
|
||||||
|
case IDEAL -> outputMatch = newOutputMatch != OutputMatch.IDEAL
|
||||||
|
? OutputMatch.BOTH : OutputMatch.IDEAL;
|
||||||
|
case OPTO_ASSEMBLY -> outputMatch = newOutputMatch != OutputMatch.OPTO_ASSEMBLY
|
||||||
|
? OutputMatch.BOTH : OutputMatch.OPTO_ASSEMBLY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a failure message based on the collected failures of this object.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String buildFailureMessage() {
|
||||||
|
StringBuilder failMsg = new StringBuilder();
|
||||||
|
failMsg.append(getIRRuleLine());
|
||||||
|
if (hasFailOnFailures()) {
|
||||||
|
failMsg.append(failOnFailures.buildFailureMessage());
|
||||||
|
}
|
||||||
|
if (hasCountsFailures()) {
|
||||||
|
failMsg.append(countsFailures.buildFailureMessage());
|
||||||
|
}
|
||||||
|
return failMsg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getIRRuleLine() {
|
||||||
|
return " * @IR rule " + irRule.getRuleId() + ": \"" + irRule.getIRAnno() + "\"" + System.lineSeparator();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.irrule;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class representing an IR matching failure of a regex of a check attribute of an IR rule.
|
||||||
|
*
|
||||||
|
* @see CheckAttributeMatchResult
|
||||||
|
* @see CheckAttribute
|
||||||
|
* @see IRRule
|
||||||
|
*/
|
||||||
|
abstract class RegexFailure {
|
||||||
|
protected final String nodeRegex;
|
||||||
|
protected final int nodeId;
|
||||||
|
protected final List<String> matches;
|
||||||
|
|
||||||
|
public RegexFailure(String nodeRegex, int nodeId, List<String> matches) {
|
||||||
|
this.nodeRegex = nodeRegex;
|
||||||
|
this.nodeId = nodeId;
|
||||||
|
this.matches = addWhiteSpacePrefixForEachLine(matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> addWhiteSpacePrefixForEachLine(List<String> matches) {
|
||||||
|
return matches
|
||||||
|
.stream()
|
||||||
|
.map(s -> s.replaceAll(System.lineSeparator(), System.lineSeparator()
|
||||||
|
+ getMatchedNodesItemWhiteSpace() + " "))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public String buildFailureMessage();
|
||||||
|
|
||||||
|
public int getMatchesCount() {
|
||||||
|
return matches.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getRegexLine() {
|
||||||
|
return " * Regex " + nodeId + ": " + nodeRegex + System.lineSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getMatchedNodesBlock() {
|
||||||
|
return getMatchedNodesHeader() + getMatchesNodeLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getMatchedNodesHeader() {
|
||||||
|
int matchCount = matches.size();
|
||||||
|
return "" + getMatchedNodesWhiteSpace() + "- " + getMatchedPrefix() + " node"
|
||||||
|
+ (matchCount != 1 ? "s (" + matchCount + ")" : "") + ":" + System.lineSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getMatchedNodesWhiteSpace() {
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected String getMatchedPrefix();
|
||||||
|
|
||||||
|
protected String getMatchesNodeLines() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
matches.forEach(match -> builder.append(getMatchedNodesItemWhiteSpace()).append("* ").append(match).append(System.lineSeparator()));
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMatchedNodesItemWhiteSpace() {
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.parser;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class of a read line from the hotspot_pid* file.
|
||||||
|
*/
|
||||||
|
abstract class AbstractLine {
|
||||||
|
private final BufferedReader reader;
|
||||||
|
protected String line;
|
||||||
|
|
||||||
|
public AbstractLine(BufferedReader reader) {
|
||||||
|
this.reader = reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLine() {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read next line and return it. If we've reached the end of the file, return NULL instead.
|
||||||
|
*/
|
||||||
|
public boolean readLine() throws IOException {
|
||||||
|
line = reader.readLine();
|
||||||
|
return line != null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.parser;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing a block line inside a PrintIdeal or PrintOptoAssembly output block read from the hotspot_pid* file.
|
||||||
|
*/
|
||||||
|
class BlockLine extends AbstractLine {
|
||||||
|
|
||||||
|
public BlockLine(BufferedReader reader) {
|
||||||
|
super(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this line an end of a PrintIdeal or PrintOptoAssembly output block?
|
||||||
|
*/
|
||||||
|
public boolean isBlockEnd() {
|
||||||
|
return line.startsWith("</");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.parser;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to read all lines of a PrintIdeal or PrintOptoAssembly block.
|
||||||
|
*/
|
||||||
|
class BlockOutputReader {
|
||||||
|
private final BufferedReader reader;
|
||||||
|
|
||||||
|
public BlockOutputReader(BufferedReader reader) {
|
||||||
|
this.reader = reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read all lines belonging to a PrintIdeal or PrintOptoAssembly output block.
|
||||||
|
*/
|
||||||
|
public String readBlock() throws IOException {
|
||||||
|
BlockLine line = new BlockLine(reader);
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
while (line.readLine() && !line.isBlockEnd()) {
|
||||||
|
builder.append(escapeXML(line.getLine())).append(System.lineSeparator());
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Need to escape XML special characters.
|
||||||
|
*/
|
||||||
|
private static String escapeXML(String line) {
|
||||||
|
if (line.contains("&")) {
|
||||||
|
line = line.replace("<", "<");
|
||||||
|
line = line.replace(">", ">");
|
||||||
|
line = line.replace(""", "\"");
|
||||||
|
line = line.replace("'", "'");
|
||||||
|
line = line.replace("&", "&");
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when facing an unexpected format during parsing of the hotspot-pid* file
|
||||||
|
*/
|
||||||
|
class FileCorruptedException extends RuntimeException {
|
||||||
|
public FileCorruptedException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.parser;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.TestFramework;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
|
||||||
|
import compiler.lib.ir_framework.shared.TestFrameworkException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to parse the PrintIdeal and PrintOptoAssembly outputs of the test class from the hotspot_pid* file and add them
|
||||||
|
* to the collection of {@link IRMethod} created by {@link IREncodingParser}.
|
||||||
|
*
|
||||||
|
* @see IRMethod
|
||||||
|
* @see IREncodingParser
|
||||||
|
*/
|
||||||
|
class HotSpotPidFileParser {
|
||||||
|
private static final Pattern COMPILE_ID_PATTERN = Pattern.compile("compile_id='(\\d+)'");
|
||||||
|
|
||||||
|
private final Pattern compileIdPatternForTestClass;
|
||||||
|
private Map<String, IRMethod> compilationsMap;
|
||||||
|
|
||||||
|
public HotSpotPidFileParser(String testClass) {
|
||||||
|
this.compileIdPatternForTestClass = Pattern.compile("compile_id='(\\d+)'.*" + Pattern.quote(testClass) + " (\\S+)");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompilationsMap(Map<String, IRMethod> compilationsMap) {
|
||||||
|
this.compilationsMap = compilationsMap;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Parse the hotspot_pid*.log file from the test VM. Read the PrintIdeal and PrintOptoAssembly outputs for all
|
||||||
|
* methods of the test class that need to be IR matched (found in compilations map).
|
||||||
|
*/
|
||||||
|
public Collection<IRMethod> parseCompilations(String hotspotPidFileName) {
|
||||||
|
try {
|
||||||
|
processFileLines(hotspotPidFileName);
|
||||||
|
return compilationsMap.values();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TestFrameworkException("Error while reading " + hotspotPidFileName, e);
|
||||||
|
} catch (FileCorruptedException e) {
|
||||||
|
throw new TestFrameworkException("Unexpected format of " + hotspotPidFileName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processFileLines(String hotspotPidFileName) throws IOException {
|
||||||
|
Map<Integer, IRMethod> compileIdMap = new HashMap<>();
|
||||||
|
try (var reader = Files.newBufferedReader(Paths.get(hotspotPidFileName))) {
|
||||||
|
Line line = new Line(reader, compileIdPatternForTestClass);
|
||||||
|
BlockOutputReader blockOutputReader = new BlockOutputReader(reader);
|
||||||
|
while (line.readLine()) {
|
||||||
|
if (line.isTestClassCompilation()) {
|
||||||
|
parseTestMethodCompileId(compileIdMap, line.getLine());
|
||||||
|
} else if (isTestMethodBlockStart(line, compileIdMap)) {
|
||||||
|
String blockOutput = blockOutputReader.readBlock();
|
||||||
|
setIRMethodOutput(blockOutput, line, compileIdMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseTestMethodCompileId(Map<Integer, IRMethod> compileIdMap, String line) {
|
||||||
|
String methodName = parseMethodName(line);
|
||||||
|
if (isTestAnnotatedMethod(methodName)) {
|
||||||
|
int compileId = getCompileId(line);
|
||||||
|
compileIdMap.put(compileId, getIrMethod(methodName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseMethodName(String line) {
|
||||||
|
Matcher matcher = compileIdPatternForTestClass.matcher(line);
|
||||||
|
TestFramework.check(matcher.find(), "must find match");
|
||||||
|
return matcher.group(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTestAnnotatedMethod(String testMethodName) {
|
||||||
|
return compilationsMap.containsKey(testMethodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IRMethod getIrMethod(String testMethodName) {
|
||||||
|
return compilationsMap.get(testMethodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private int getCompileId(String line) {
|
||||||
|
Matcher matcher = COMPILE_ID_PATTERN.matcher(line);
|
||||||
|
if (!matcher.find()) {
|
||||||
|
throw new FileCorruptedException("Unexpected format found on this line: " + line);
|
||||||
|
}
|
||||||
|
return Integer.parseInt(matcher.group(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTestMethodBlockStart(Line line, Map<Integer, IRMethod> compileIdMap) {
|
||||||
|
return line.isBlockStart() && isTestClassMethodBlock(line, compileIdMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTestClassMethodBlock(Line line, Map<Integer, IRMethod> compileIdMap) {
|
||||||
|
return compileIdMap.containsKey(getCompileId(line.getLine()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIRMethodOutput(String blockOutput, Line blockStartLine, Map<Integer, IRMethod> compileIdMap) {
|
||||||
|
IRMethod irMethod = compileIdMap.get(getCompileId(blockStartLine.getLine()));
|
||||||
|
setIRMethodOutput(blockOutput, blockStartLine, irMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setIRMethodOutput(String blockOutput, Line blockStartLine, IRMethod irMethod) {
|
||||||
|
if (blockStartLine.isPrintIdealStart()) {
|
||||||
|
irMethod.setIdealOutput(blockOutput);
|
||||||
|
} else {
|
||||||
|
irMethod.setOptoAssemblyOutput(blockOutput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.parser;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.IR;
|
||||||
|
import compiler.lib.ir_framework.TestFramework;
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
|
||||||
|
import compiler.lib.ir_framework.shared.TestFormat;
|
||||||
|
import compiler.lib.ir_framework.shared.TestFrameworkException;
|
||||||
|
import compiler.lib.ir_framework.test.IREncodingPrinter;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to parse the IR encoding emitted by the test VM and creating {@link IRMethod} objects for each entry.
|
||||||
|
*
|
||||||
|
* @see IRMethod
|
||||||
|
*/
|
||||||
|
class IREncodingParser {
|
||||||
|
|
||||||
|
private static final boolean PRINT_IR_ENCODING = Boolean.parseBoolean(System.getProperty("PrintIREncoding", "false"));
|
||||||
|
private static final Pattern IR_ENCODING_PATTERN =
|
||||||
|
Pattern.compile("(?<=" + IREncodingPrinter.START + "\r?\n).*\\R([\\s\\S]*)(?=" + IREncodingPrinter.END + ")");
|
||||||
|
|
||||||
|
private final Map<String, IRMethod> compilations;
|
||||||
|
private final Class<?> testClass;
|
||||||
|
|
||||||
|
public IREncodingParser(Class<?> testClass) {
|
||||||
|
this.testClass = testClass;
|
||||||
|
this.compilations = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, IRMethod> parseIRMethods(String irEncoding) {
|
||||||
|
if (TestFramework.VERBOSE || PRINT_IR_ENCODING) {
|
||||||
|
System.out.println("Read IR encoding from test VM:");
|
||||||
|
System.out.println(irEncoding);
|
||||||
|
}
|
||||||
|
createCompilationsMap(irEncoding, testClass);
|
||||||
|
// We could have found format errors in @IR annotations. Report them now with an exception.
|
||||||
|
TestFormat.throwIfAnyFailures();
|
||||||
|
return compilations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up a map testname -> IRMethod (containing the PrintIdeal and PrintOptoAssembly output for testname).
|
||||||
|
*/
|
||||||
|
private void createCompilationsMap(String irEncoding, Class<?> testClass) {
|
||||||
|
Map<String, int[]> irRulesMap = parseIREncoding(irEncoding);
|
||||||
|
createIRMethodsWithEncoding(testClass, irRulesMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the IR encoding emitted by the test VM to decide if an @IR rule must be checked for a method.
|
||||||
|
*/
|
||||||
|
private Map<String, int[]> parseIREncoding(String irEncoding) {
|
||||||
|
Map<String, int[]> irRulesMap = new HashMap<>();
|
||||||
|
String[] irEncodingLines = getIREncodingLines(irEncoding);
|
||||||
|
for (String s : irEncodingLines) {
|
||||||
|
String line = s.trim();
|
||||||
|
String[] splitLine = line.split(",");
|
||||||
|
if (splitLine.length < 2) {
|
||||||
|
throw new TestFrameworkException("Invalid IR match rule encoding. No comma found: " + splitLine[0]);
|
||||||
|
}
|
||||||
|
String testName = splitLine[0];
|
||||||
|
int[] irRulesIdx = getRuleIndexes(splitLine);
|
||||||
|
irRulesMap.put(testName, irRulesIdx);
|
||||||
|
}
|
||||||
|
return irRulesMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the IR encoding lines without header, explanation line and footer and return them in an array.
|
||||||
|
*/
|
||||||
|
private String[] getIREncodingLines(String irEncoding) {
|
||||||
|
Matcher matcher = IR_ENCODING_PATTERN.matcher(irEncoding);
|
||||||
|
TestFramework.check(matcher.find(), "Did not find IR encoding");
|
||||||
|
String lines = matcher.group(1).trim();
|
||||||
|
if (lines.isEmpty()) {
|
||||||
|
// Nothing to IR match.
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
return lines.split("\\R");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse rule indexes from IR encoding line of the format: <method,idx1,idx2,...>
|
||||||
|
*/
|
||||||
|
private int[] getRuleIndexes(String[] splitLine) {
|
||||||
|
int[] irRulesIdx = new int[splitLine.length - 1];
|
||||||
|
for (int i = 1; i < splitLine.length; i++) {
|
||||||
|
try {
|
||||||
|
irRulesIdx[i - 1] = Integer.parseInt(splitLine[i]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new TestFrameworkException("Invalid IR match rule encoding. No number found: " + splitLine[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return irRulesIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createIRMethodsWithEncoding(Class<?> testClass, Map<String, int[]> irRulesMap) {
|
||||||
|
for (Method m : testClass.getDeclaredMethods()) {
|
||||||
|
IR[] irAnnos = m.getAnnotationsByType(IR.class);
|
||||||
|
if (irAnnos.length > 0) {
|
||||||
|
// Validation of legal @IR attributes and placement of the annotation was already done in Test VM.
|
||||||
|
int[] irRuleIds = irRulesMap.get(m.getName());
|
||||||
|
validateIRRuleIds(m, irAnnos, irRuleIds);
|
||||||
|
if (hasAnyApplicableIRRules(irRuleIds)) {
|
||||||
|
compilations.put(m.getName(), new IRMethod(m, irRuleIds, irAnnos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateIRRuleIds(Method m, IR[] irAnnos, int[] ids) {
|
||||||
|
TestFramework.check(ids != null, "Should find method name in validIrRulesMap for " + m);
|
||||||
|
TestFramework.check(ids.length > 0, "Did not find any rule indices for " + m);
|
||||||
|
TestFramework.check((ids[0] >= 1 || ids[0] == IREncodingPrinter.NO_RULE_APPLIED)
|
||||||
|
&& ids[ids.length - 1] <= irAnnos.length,
|
||||||
|
"Invalid IR rule index found in validIrRulesMap for " + m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the list of IR rules contain any applicable IR rules for the given conditions?
|
||||||
|
*/
|
||||||
|
private boolean hasAnyApplicableIRRules(int[] irRuleIds) {
|
||||||
|
return irRuleIds[0] != IREncodingPrinter.NO_RULE_APPLIED;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.parser;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to parse the PrintIdeal and PrintOptoAssembly outputs of the test class and store them into a collection
|
||||||
|
* of dedicated IRMethod objects used throughout IR matching.
|
||||||
|
*
|
||||||
|
* @see IRMethod
|
||||||
|
*/
|
||||||
|
public class IRMethodParser {
|
||||||
|
private final IREncodingParser irEncodingParser;
|
||||||
|
private final HotSpotPidFileParser hotSpotPidFileParser;
|
||||||
|
|
||||||
|
public IRMethodParser(Class<?> testClass) {
|
||||||
|
this.irEncodingParser = new IREncodingParser(testClass);
|
||||||
|
this.hotSpotPidFileParser = new HotSpotPidFileParser(testClass.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the IR encoding and hotspot_pid* file to create a collection of {@link IRMethod} objects.
|
||||||
|
* Return null if there are no applicable @IR rules in any method of the test class.
|
||||||
|
*/
|
||||||
|
public Collection<IRMethod> parse(String hotspotPidFileName, String irEncoding) {
|
||||||
|
Map<String, IRMethod> compilationsMap = irEncodingParser.parseIRMethods(irEncoding);
|
||||||
|
if (!compilationsMap.isEmpty()) {
|
||||||
|
hotSpotPidFileParser.setCompilationsMap(compilationsMap);
|
||||||
|
return hotSpotPidFileParser.parseCompilations(hotspotPidFileName);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.driver.irmatching.parser;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing a normal line read from the hotspot_pid* file.
|
||||||
|
*/
|
||||||
|
class Line extends AbstractLine {
|
||||||
|
private final Pattern compileIdPatternForTestClass;
|
||||||
|
|
||||||
|
public Line(BufferedReader reader, Pattern compileIdPatternForTestClass) {
|
||||||
|
super(reader);
|
||||||
|
this.compileIdPatternForTestClass = compileIdPatternForTestClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this line a start of a @Test annotated method? We only care about test class entries. There might be non-class
|
||||||
|
* entries as well if user specified additional compile commands. Ignore these.
|
||||||
|
*/
|
||||||
|
public boolean isTestClassCompilation() {
|
||||||
|
if (isCompilation()) {
|
||||||
|
Matcher matcher = compileIdPatternForTestClass.matcher(line);
|
||||||
|
return matcher.find();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this header a C2 non-OSR compilation header entry?
|
||||||
|
*/
|
||||||
|
public boolean isCompilation() {
|
||||||
|
return line.startsWith("<task_queued") && notOSRCompilation() && notC2Compilation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OSR compilations have compile_kind set.
|
||||||
|
*/
|
||||||
|
private boolean notOSRCompilation() {
|
||||||
|
return !line.contains("compile_kind='");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-C2 compilations have level set.
|
||||||
|
*/
|
||||||
|
private boolean notC2Compilation() {
|
||||||
|
return !line.contains("level='");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this line a start of a PrintIdeal or PrintOptoAssembly output block?
|
||||||
|
*/
|
||||||
|
public boolean isBlockStart() {
|
||||||
|
return isPrintIdealStart() || isPrintOptoAssemblyStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this line a start of a PrintIdeal output block?
|
||||||
|
*/
|
||||||
|
public boolean isPrintIdealStart() {
|
||||||
|
// Ignore OSR compilations which have compile_kind set.
|
||||||
|
return line.startsWith("<ideal") && notOSRCompilation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this line a start of a PrintOptoAssembly output block?
|
||||||
|
*/
|
||||||
|
private boolean isPrintOptoAssemblyStart() {
|
||||||
|
// Ignore OSR compilations which have compile_kind set.
|
||||||
|
return line.startsWith("<opto_assembly") && notOSRCompilation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.shared;
|
||||||
|
|
||||||
|
import java.util.function.BiPredicate;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison result of parsing a constraint with {@link ComparisonConstraintParser#parse(String, Function, String)}.
|
||||||
|
*/
|
||||||
|
public class Comparison<T extends Comparable<T>> {
|
||||||
|
private final T givenValue; // Right hand side
|
||||||
|
private final BiPredicate<T, T> comparisonPredicate;
|
||||||
|
private final String comparator;
|
||||||
|
|
||||||
|
public Comparison(T givenValue, String comparator, BiPredicate<T, T> comparisonPredicate) {
|
||||||
|
this.givenValue = givenValue;
|
||||||
|
this.comparator = comparator;
|
||||||
|
this.comparisonPredicate = comparisonPredicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getGivenValue() {
|
||||||
|
return givenValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComparator() {
|
||||||
|
return comparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison: foundValue OP givenValue
|
||||||
|
*/
|
||||||
|
public boolean compare(T foundValue) {
|
||||||
|
return comparisonPredicate.test(foundValue, givenValue);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* 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.shared;
|
||||||
|
|
||||||
|
import java.util.function.BiPredicate;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to parse a comparator either in the applyIf* or in the counts properties of an @IR rules.
|
||||||
|
*/
|
||||||
|
public class ComparisonConstraintParser<T extends Comparable<T>> {
|
||||||
|
|
||||||
|
private enum Comparator {
|
||||||
|
ONE_CHAR, TWO_CHARS
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Comparable<T>> Comparison<T> parse(String constraint, Function<String, T> parseFunction,
|
||||||
|
String postfixErrorMsg) {
|
||||||
|
try {
|
||||||
|
return parseConstraintAndValue(constraint, parseFunction);
|
||||||
|
} catch (EmptyConstraintException e) {
|
||||||
|
TestFormat.fail("Provided empty value " + postfixErrorMsg);
|
||||||
|
throw new UnreachableCodeException();
|
||||||
|
} catch (MissingConstraintValueException e) {
|
||||||
|
TestFormat.fail("Provided empty value after comparator \"" + e.getComparator() + "\" " + postfixErrorMsg);
|
||||||
|
throw new UnreachableCodeException();
|
||||||
|
} catch (InvalidComparatorException e) {
|
||||||
|
TestFormat.fail("Provided invalid comparator \"" + e.getComparator() + "\" " + postfixErrorMsg);
|
||||||
|
throw new UnreachableCodeException();
|
||||||
|
} catch (InvalidConstraintValueException e) {
|
||||||
|
String comparator = e.getComparator();
|
||||||
|
if (!comparator.isEmpty()) {
|
||||||
|
comparator = " after comparator \"" + comparator + "\"";
|
||||||
|
}
|
||||||
|
TestFormat.fail("Provided invalid value \"" + e.getInvalidValue() + "\""
|
||||||
|
+ comparator + " " + postfixErrorMsg);
|
||||||
|
throw new UnreachableCodeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends Comparable<T>> Comparison<T> parseConstraintAndValue(String constraint,
|
||||||
|
Function<String, T> parseFunction) throws
|
||||||
|
EmptyConstraintException, MissingConstraintValueException,
|
||||||
|
InvalidComparatorException, InvalidConstraintValueException {
|
||||||
|
ParsedResult<T> result = parse(constraint);
|
||||||
|
T givenValue = parseGivenValue(parseFunction, result);
|
||||||
|
return new Comparison<>(givenValue, result.comparator, result.comparisonPredicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends Comparable<T>> ParsedResult<T> parse(String constraint) throws
|
||||||
|
EmptyConstraintException, MissingConstraintValueException, InvalidComparatorException {
|
||||||
|
constraint = constraint.trim();
|
||||||
|
if (constraint.isEmpty()) {
|
||||||
|
throw new EmptyConstraintException();
|
||||||
|
}
|
||||||
|
switch (constraint.charAt(0)) {
|
||||||
|
case '<' -> {
|
||||||
|
throwIfNoValueAfterComparator(constraint, Comparator.ONE_CHAR);
|
||||||
|
if (constraint.charAt(1) == '=') {
|
||||||
|
throwIfNoValueAfterComparator(constraint, Comparator.TWO_CHARS);
|
||||||
|
return new ParsedResult<>(constraint.substring(2).trim(), "<=", (x, y) -> x.compareTo(y) <= 0);
|
||||||
|
} else {
|
||||||
|
return new ParsedResult<>(constraint.substring(1).trim(), "<", (x, y) -> x.compareTo(y) < 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case '>' -> {
|
||||||
|
throwIfNoValueAfterComparator(constraint, Comparator.ONE_CHAR);
|
||||||
|
if (constraint.charAt(1) == '=') {
|
||||||
|
throwIfNoValueAfterComparator(constraint, Comparator.TWO_CHARS);
|
||||||
|
return new ParsedResult<>(constraint.substring(2).trim(), ">=", (x, y) -> x.compareTo(y) >= 0);
|
||||||
|
} else {
|
||||||
|
return new ParsedResult<>(constraint.substring(1).trim(), ">", (x, y) -> x.compareTo(y) > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case '!' -> {
|
||||||
|
throwIfNoValueAfterComparator(constraint, Comparator.ONE_CHAR);
|
||||||
|
if (constraint.charAt(1) != '=') {
|
||||||
|
throw new InvalidComparatorException("!");
|
||||||
|
}
|
||||||
|
throwIfNoValueAfterComparator(constraint, Comparator.TWO_CHARS);
|
||||||
|
return new ParsedResult<>(constraint.substring(2).trim(), "!=", (x, y) -> x.compareTo(y) != 0);
|
||||||
|
}
|
||||||
|
case '=' -> { // Allowed syntax, equivalent to not using any symbol.
|
||||||
|
throwIfNoValueAfterComparator(constraint, Comparator.ONE_CHAR);
|
||||||
|
return new ParsedResult<>(constraint.substring(1).trim(), "=", (x, y) -> x.compareTo(y) == 0);
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
return new ParsedResult<>(constraint.trim(), "=", (x, y) -> x.compareTo(y) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void throwIfNoValueAfterComparator(String constraint, Comparator comparator) throws MissingConstraintValueException {
|
||||||
|
switch (comparator) {
|
||||||
|
case ONE_CHAR -> {
|
||||||
|
if (constraint.length() == 1) {
|
||||||
|
throw new MissingConstraintValueException(constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case TWO_CHARS -> {
|
||||||
|
if (constraint.length() == 2) {
|
||||||
|
throw new MissingConstraintValueException(constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends Comparable<T>> T parseGivenValue(Function<String, T> parseFunction, ParsedResult<T> result)
|
||||||
|
throws InvalidConstraintValueException {
|
||||||
|
try {
|
||||||
|
return parseFunction.apply(result.value);
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e) {
|
||||||
|
throw new InvalidConstraintValueException(result.value, result.comparator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ParsedResult<T> {
|
||||||
|
public String value;
|
||||||
|
public BiPredicate<T, T> comparisonPredicate;
|
||||||
|
public String comparator;
|
||||||
|
|
||||||
|
public ParsedResult(String value, String comparator,BiPredicate<T, T> comparisonPredicate) {
|
||||||
|
this.value = value;
|
||||||
|
this.comparator = comparator;
|
||||||
|
this.comparisonPredicate = comparisonPredicate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.shared;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when {@link ComparisonConstraintParser} cannot find a constraint.
|
||||||
|
*/
|
||||||
|
class EmptyConstraintException extends Exception {
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.shared;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception threw when {@link ComparisonConstraintParser} parses an invalid comparator.
|
||||||
|
*/
|
||||||
|
public class InvalidComparatorException extends Exception {
|
||||||
|
private final String comparator;
|
||||||
|
|
||||||
|
public InvalidComparatorException(String comparator) {
|
||||||
|
this.comparator = comparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComparator() {
|
||||||
|
return comparator;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.shared;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when {@link ComparisonConstraintParser} parses an invalid value.
|
||||||
|
*/
|
||||||
|
class InvalidConstraintValueException extends Exception {
|
||||||
|
private final String invalidValue;
|
||||||
|
private final String comparator;
|
||||||
|
|
||||||
|
public InvalidConstraintValueException(String invalidValue, String comparator) {
|
||||||
|
this.invalidValue = invalidValue;
|
||||||
|
this.comparator = comparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInvalidValue() {
|
||||||
|
return invalidValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComparator() {
|
||||||
|
return comparator;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.shared;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when {@link ComparisonConstraintParser} cannot find a value in a constraint after a comparator.
|
||||||
|
*/
|
||||||
|
class MissingConstraintValueException extends Exception {
|
||||||
|
private final String comparator;
|
||||||
|
|
||||||
|
public MissingConstraintValueException(String comparator) {
|
||||||
|
this.comparator = comparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComparator() {
|
||||||
|
return comparator;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2021, 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.shared;
|
|
||||||
|
|
||||||
import java.util.function.BiPredicate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class to parse a comparator either in the applyIf* or in the counts properties of an @IR rules.
|
|
||||||
*/
|
|
||||||
public class ParsedComparator<T extends Comparable<T>> {
|
|
||||||
private final String strippedString;
|
|
||||||
private final BiPredicate<T, T> predicate;
|
|
||||||
private final String comparator;
|
|
||||||
|
|
||||||
public ParsedComparator(String strippedString, BiPredicate<T, T> predicate, String comparator) {
|
|
||||||
this.strippedString = strippedString;
|
|
||||||
this.predicate = predicate;
|
|
||||||
this.comparator = comparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStrippedString() {
|
|
||||||
return strippedString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BiPredicate<T, T> getPredicate() {
|
|
||||||
return predicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getComparator() {
|
|
||||||
return comparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return parsed comparator object which provides the predicate to perform the test.
|
|
||||||
* Allowed comparators: <, <=, >, =>, =, !=
|
|
||||||
*/
|
|
||||||
public static <T extends Comparable<T>> ParsedComparator<T> parseComparator(String value) throws CheckedTestFrameworkException {
|
|
||||||
BiPredicate<T, T> comparison;
|
|
||||||
value = value.trim();
|
|
||||||
String comparator = "";
|
|
||||||
switch (value.charAt(0)) {
|
|
||||||
case '<':
|
|
||||||
if (value.charAt(1) == '=') {
|
|
||||||
comparator = "<=";
|
|
||||||
comparison = (x, y) -> x.compareTo(y) <= 0;
|
|
||||||
value = value.substring(2).trim();
|
|
||||||
} else {
|
|
||||||
comparator = "<";
|
|
||||||
comparison = (x, y) -> x.compareTo(y) < 0;
|
|
||||||
value = value.substring(1).trim();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
if (value.charAt(1) == '=') {
|
|
||||||
comparator = ">=";
|
|
||||||
comparison = (x, y) -> x.compareTo(y) >= 0;
|
|
||||||
value = value.substring(2).trim();
|
|
||||||
} else {
|
|
||||||
comparator = ">";
|
|
||||||
comparison = (x, y) -> x.compareTo(y) > 0;
|
|
||||||
value = value.substring(1).trim();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '!':
|
|
||||||
if (value.charAt(1) != '=') {
|
|
||||||
throw new CheckedTestFrameworkException(value.substring(0, 1));
|
|
||||||
}
|
|
||||||
comparator = "!=";
|
|
||||||
comparison = (x, y) -> x.compareTo(y) != 0;
|
|
||||||
value = value.substring(2).trim();
|
|
||||||
break;
|
|
||||||
case '=': // Allowed syntax, equivalent to not using any symbol.
|
|
||||||
comparator = "=";
|
|
||||||
value = value.substring(1).trim();
|
|
||||||
// Fall through
|
|
||||||
default:
|
|
||||||
comparison = (x, y) -> x.compareTo(y) == 0;
|
|
||||||
value = value.trim();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return new ParsedComparator<>(value, comparison, comparator);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -53,7 +53,7 @@ public class TestFormat {
|
||||||
FAILURES.add(failureMessage);
|
FAILURES.add(failureMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reportIfAnyFailures() {
|
public static void throwIfAnyFailures() {
|
||||||
if (FAILURES.isEmpty()) {
|
if (FAILURES.isEmpty()) {
|
||||||
// No format violation detected.
|
// No format violation detected.
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.shared;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error reporting of the IR framework is throwing exceptions unconditionally in separate methods. The calling methods,
|
||||||
|
* however, do not see these exceptions. As a result, Java and/or some IDEs could complain about impossible states
|
||||||
|
* (e.g. uninitialized variables, null pointer dereferences etc. even though an exception will be thrown earlier).
|
||||||
|
* To avoid that, throw an instance of this class instead.
|
||||||
|
*/
|
||||||
|
class UnreachableCodeException extends RuntimeException {
|
||||||
|
public UnreachableCodeException() {
|
||||||
|
super("Unreachable code");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -37,7 +37,7 @@ import java.util.function.Function;
|
||||||
/**
|
/**
|
||||||
* Prints an encoding to the dedicated test framework socket whether @IR rules of @Test methods should be applied or not.
|
* Prints an encoding to the dedicated test framework socket whether @IR rules of @Test methods should be applied or not.
|
||||||
* This is done during the execution of the test VM by checking the active VM flags. This encoding is eventually parsed
|
* This is done during the execution of the test VM by checking the active VM flags. This encoding is eventually parsed
|
||||||
* and checked by the IRMatcher class in the driver VM after the termination of the test VM.
|
* and checked by the IRMatcher class in the driver VM after the termination of the test VM. IR rule indices start at 1.
|
||||||
*/
|
*/
|
||||||
public class IREncodingPrinter {
|
public class IREncodingPrinter {
|
||||||
public static final String START = "##### IRMatchRulesEncoding - used by TestFramework #####";
|
public static final String START = "##### IRMatchRulesEncoding - used by TestFramework #####";
|
||||||
|
@ -73,7 +73,7 @@ public class IREncodingPrinter {
|
||||||
ruleIndex = i + 1;
|
ruleIndex = i + 1;
|
||||||
try {
|
try {
|
||||||
if (shouldApplyIrRule(irAnno)) {
|
if (shouldApplyIrRule(irAnno)) {
|
||||||
validRules.add(i);
|
validRules.add(ruleIndex);
|
||||||
}
|
}
|
||||||
} catch (TestFormatException e) {
|
} catch (TestFormatException e) {
|
||||||
// Catch logged failure and continue to check other IR annotations.
|
// Catch logged failure and continue to check other IR annotations.
|
||||||
|
@ -206,11 +206,11 @@ public class IREncodingPrinter {
|
||||||
}
|
}
|
||||||
actualFlagValue = LONG_GETTERS.stream().map(f -> f.apply(flag)).filter(Objects::nonNull).findAny().orElse(null);
|
actualFlagValue = LONG_GETTERS.stream().map(f -> f.apply(flag)).filter(Objects::nonNull).findAny().orElse(null);
|
||||||
if (actualFlagValue != null) {
|
if (actualFlagValue != null) {
|
||||||
return checkLongFlag(flag, value, (Long) actualFlagValue);
|
return checkFlag(Long::parseLong, "integer", flag, value, (Long) actualFlagValue);
|
||||||
}
|
}
|
||||||
actualFlagValue = WHITE_BOX.getDoubleVMFlag(flag);
|
actualFlagValue = WHITE_BOX.getDoubleVMFlag(flag);
|
||||||
if (actualFlagValue != null) {
|
if (actualFlagValue != null) {
|
||||||
return checkDoubleFlag(flag, value, (Double) actualFlagValue);
|
return checkFlag(Double::parseDouble, "floating point", flag, value, (Double) actualFlagValue);
|
||||||
}
|
}
|
||||||
actualFlagValue = WHITE_BOX.getStringVMFlag(flag);
|
actualFlagValue = WHITE_BOX.getStringVMFlag(flag);
|
||||||
if (actualFlagValue != null) {
|
if (actualFlagValue != null) {
|
||||||
|
@ -242,60 +242,20 @@ public class IREncodingPrinter {
|
||||||
return booleanValue == actualFlagValue;
|
return booleanValue == actualFlagValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkLongFlag(String flag, String value, long actualFlagValue) {
|
private <T extends Comparable<T>> boolean checkFlag(Function<String, T> parseFunction, String kind, String flag,
|
||||||
long longValue;
|
String value, T actualFlagValue) {
|
||||||
ParsedComparator<Long> parsedComparator;
|
|
||||||
try {
|
try {
|
||||||
parsedComparator = ParsedComparator.parseComparator(value);
|
String postFixErrorMsg = "for " + kind + " based flag \"" + flag + "\"" + failAt();
|
||||||
} catch (CheckedTestFrameworkException e) {
|
Comparison<T> comparison = ComparisonConstraintParser.parse(value, parseFunction, postFixErrorMsg);
|
||||||
TestFormat.failNoThrow("Invalid comparator in \"" + value + "\" for integer based flag " + flag + failAt());
|
return comparison.compare(actualFlagValue);
|
||||||
return false;
|
} catch (TestFormatException e) {
|
||||||
} catch (IndexOutOfBoundsException e) {
|
// Format exception, do not apply rule.
|
||||||
TestFormat.failNoThrow("Provided empty value for integer based flag " + flag + failAt());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
longValue = Long.parseLong(parsedComparator.getStrippedString());
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
String comparator = parsedComparator.getComparator();
|
|
||||||
if (!comparator.isEmpty()) {
|
|
||||||
comparator = "after comparator \"" + parsedComparator.getComparator() + "\"";
|
|
||||||
}
|
|
||||||
TestFormat.failNoThrow("Invalid value \"" + parsedComparator.getStrippedString() + "\" "
|
|
||||||
+ comparator + " for integer based flag " + flag + failAt());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return parsedComparator.getPredicate().test(actualFlagValue, longValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkDoubleFlag(String flag, String value, double actualFlagValue) {
|
|
||||||
double doubleValue;
|
|
||||||
ParsedComparator<Double> parsedComparator;
|
|
||||||
try {
|
|
||||||
parsedComparator = ParsedComparator.parseComparator(value);
|
|
||||||
} catch (CheckedTestFrameworkException e) {
|
|
||||||
TestFormat.failNoThrow("Invalid comparator in \"" + value + "\" for floating point based flag " + flag + failAt());
|
|
||||||
return false;
|
|
||||||
} catch (IndexOutOfBoundsException e) {
|
|
||||||
TestFormat.failNoThrow("Provided empty value for floating point based flag " + flag + failAt());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
doubleValue = Double.parseDouble(parsedComparator.getStrippedString());
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
String comparator = parsedComparator.getComparator();
|
|
||||||
if (!comparator.isEmpty()) {
|
|
||||||
comparator = "after comparator \"" + parsedComparator.getComparator() + "\"";
|
|
||||||
}
|
|
||||||
TestFormat.failNoThrow("Invalid value \"" + parsedComparator.getStrippedString() + "\" "
|
|
||||||
+ comparator + " for floating point based flag " + flag + failAt());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return parsedComparator.getPredicate().test(actualFlagValue, doubleValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String failAt() {
|
private String failAt() {
|
||||||
return " for @IR rule " + ruleIndex + " at " + method;
|
return " in @IR rule " + ruleIndex + " at " + method;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void emit() {
|
public void emit() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -267,7 +267,7 @@ public class TestVM {
|
||||||
if (PRINT_VALID_IR_RULES) {
|
if (PRINT_VALID_IR_RULES) {
|
||||||
irMatchRulePrinter.emit();
|
irMatchRulePrinter.emit();
|
||||||
}
|
}
|
||||||
TestFormat.reportIfAnyFailures();
|
TestFormat.throwIfAnyFailures();
|
||||||
declaredTests.clear();
|
declaredTests.clear();
|
||||||
testMethodMap.clear();
|
testMethodMap.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,9 +37,6 @@ package compiler.vectorapi;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import compiler.lib.ir_framework.*;
|
import compiler.lib.ir_framework.*;
|
||||||
import compiler.lib.ir_framework.driver.IRViolationException;
|
|
||||||
import jdk.test.lib.Asserts;
|
|
||||||
import jdk.test.lib.Asserts;
|
|
||||||
import jdk.test.lib.Utils;
|
import jdk.test.lib.Utils;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
package ir_framework.examples;
|
package ir_framework.examples;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.*;
|
import compiler.lib.ir_framework.*;
|
||||||
import compiler.lib.ir_framework.driver.IRViolationException;
|
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
package ir_framework.tests;
|
package ir_framework.tests;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.*;
|
import compiler.lib.ir_framework.*;
|
||||||
import compiler.lib.ir_framework.driver.IRViolationException;
|
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
|
||||||
import compiler.lib.ir_framework.driver.TestVMException;
|
import compiler.lib.ir_framework.driver.TestVMException;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
package ir_framework.tests;
|
package ir_framework.tests;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.*;
|
import compiler.lib.ir_framework.*;
|
||||||
import compiler.lib.ir_framework.driver.IRViolationException;
|
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
|
||||||
import jdk.test.lib.Asserts;
|
import jdk.test.lib.Asserts;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
package ir_framework.tests;
|
package ir_framework.tests;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.*;
|
import compiler.lib.ir_framework.*;
|
||||||
import compiler.lib.ir_framework.driver.IRViolationException;
|
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
|
||||||
import jdk.test.lib.Asserts;
|
import jdk.test.lib.Asserts;
|
||||||
import jdk.test.lib.Platform;
|
import jdk.test.lib.Platform;
|
||||||
import sun.hotspot.WhiteBox;
|
import sun.hotspot.WhiteBox;
|
||||||
|
@ -60,7 +60,7 @@ public class TestIRMatching {
|
||||||
private static void addException(Exception e) {
|
private static void addException(Exception e) {
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
System.err.flush();
|
System.err.flush();
|
||||||
exceptions.put(e, baos.toString() + System.lineSeparator() + baosErr.toString());
|
exceptions.put(e, baos + System.lineSeparator() + baosErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -285,20 +285,20 @@ public class TestIRMatching {
|
||||||
runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=50");
|
runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=50");
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
String output = baos.toString();
|
String output = baos.toString();
|
||||||
findIrIds(output, "testMatchAllIf50", 0, 21);
|
findIrIds(output, "testMatchAllIf50", 1, 22);
|
||||||
findIrIds(output, "testMatchNoneIf50", -1, -1);
|
findIrIds(output, "testMatchNoneIf50", -1, -1);
|
||||||
|
|
||||||
runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=49");
|
runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=49");
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
output = baos.toString();
|
output = baos.toString();
|
||||||
findIrIds(output, "testMatchAllIf50", 4, 6, 13, 18);
|
findIrIds(output, "testMatchAllIf50", 5, 7, 14, 19);
|
||||||
findIrIds(output, "testMatchNoneIf50", 0, 3, 8, 10, 17, 22);
|
findIrIds(output, "testMatchNoneIf50", 1, 4, 9, 11, 18, 23);
|
||||||
|
|
||||||
runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=51");
|
runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=51");
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
output = baos.toString();
|
output = baos.toString();
|
||||||
findIrIds(output, "testMatchAllIf50", 7, 12, 19, 21);
|
findIrIds(output, "testMatchAllIf50", 8, 13, 20, 22);
|
||||||
findIrIds(output, "testMatchNoneIf50", 4, 7, 11, 16, 20, 22);
|
findIrIds(output, "testMatchNoneIf50", 5, 8, 12, 17, 21, 23);
|
||||||
System.setOut(oldOut);
|
System.setOut(oldOut);
|
||||||
System.setErr(oldErr);
|
System.setErr(oldErr);
|
||||||
|
|
||||||
|
@ -395,7 +395,7 @@ public class TestIRMatching {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!output.contains(builder.toString())) {
|
if (!output.contains(builder.toString())) {
|
||||||
addException(new RuntimeException("Could not find encoding: \"" + builder.toString() + System.lineSeparator()));
|
addException(new RuntimeException("Could not find encoding: \"" + builder + System.lineSeparator()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -550,20 +550,20 @@ class MultipleFailOnBad {
|
||||||
class FlagComparisons {
|
class FlagComparisons {
|
||||||
// Applies all IR rules if TLABRefillWasteFraction=50
|
// Applies all IR rules if TLABRefillWasteFraction=50
|
||||||
@Test
|
@Test
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "50"}) // Index 0
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "50"}) // Index 1
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "=50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "=50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "= 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "= 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " = 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " = 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<=50"}) // Index 4
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<=50"}) // Index 5
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<= 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<= 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " <= 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " <= 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">=50"}) // Index 7
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">=50"}) // Index 8
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">= 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">= 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " >= 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " >= 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">49"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">49"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "> 49"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "> 49"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " > 49"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " > 49"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<51"}) // Index 13
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<51"}) // Index 14
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "< 51"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "< 51"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " < 51"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " < 51"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!=51"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!=51"})
|
||||||
|
@ -571,34 +571,34 @@ class FlagComparisons {
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " != 51"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " != 51"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!=49"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!=49"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!= 49"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!= 49"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " != 49"}) // Index 21
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " != 49"}) // Index 22
|
||||||
public void testMatchAllIf50() {}
|
public void testMatchAllIf50() {}
|
||||||
|
|
||||||
// Applies no IR rules if TLABRefillWasteFraction=50
|
// Applies no IR rules if TLABRefillWasteFraction=50
|
||||||
@Test
|
@Test
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "49"}) // Index 0
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "49"}) // Index 1
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "=49"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "=49"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "= 49"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "= 49"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " = 49"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " = 49"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "51"}) // Index 4
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "51"}) // Index 5
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "=51"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "=51"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "= 51"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "= 51"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " = 51"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " = 51"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<=49"}) // Index 8
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<=49"}) // Index 9
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<= 49"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<= 49"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " <= 49"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " <= 49"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">=51"}) // Index 11
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">=51"}) // Index 12
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">= 51"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">= 51"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " >= 51"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " >= 51"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "> 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "> 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " > 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " > 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<50"}) // Index 17
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<50"}) // Index 18
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "< 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "< 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " < 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " < 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!=50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!=50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!= 50"})
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!= 50"})
|
||||||
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " != 50"}) // Index 22
|
@IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " != 50"}) // Index 23
|
||||||
public void testMatchNoneIf50() {}
|
public void testMatchNoneIf50() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,14 +814,14 @@ class BadCount {
|
||||||
int iFld;
|
int iFld;
|
||||||
int result;
|
int result;
|
||||||
@Test
|
@Test
|
||||||
@IR(counts = {IRNode.LOAD, "!= 1"})
|
@IR(counts = {IRNode.LOAD, "!= 1"}) // fail
|
||||||
@IR(counts = {IRNode.STORE, "> 0"})
|
@IR(counts = {IRNode.STORE, "> 0"})
|
||||||
public void bad1() {
|
public void bad1() {
|
||||||
result = iFld;
|
result = iFld;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@IR(counts = {IRNode.LOAD, "1"})
|
@IR(counts = {IRNode.LOAD, "1"}) // fail
|
||||||
@IR(counts = {IRNode.STORE, "< 1"})
|
@IR(counts = {IRNode.STORE, "< 1"})
|
||||||
public void bad2() {
|
public void bad2() {
|
||||||
result = iFld;
|
result = iFld;
|
||||||
|
@ -829,8 +829,8 @@ class BadCount {
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@IR(counts = {IRNode.LOAD, "0"})
|
@IR(counts = {IRNode.LOAD, "0"}) // fail
|
||||||
@IR(counts = {IRNode.STORE, " <= 0"})
|
@IR(counts = {IRNode.STORE, " <= 0"}) // fail
|
||||||
public void bad3() {
|
public void bad3() {
|
||||||
result = iFld;
|
result = iFld;
|
||||||
}
|
}
|
||||||
|
@ -1514,7 +1514,7 @@ abstract class Constraint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Asserts.assertTrue(matched, toString() + " should have been matched");
|
Asserts.assertTrue(matched, this + " should have been matched");
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected void checkIRRule(String irRule);
|
abstract protected void checkIRRule(String irRule);
|
||||||
|
@ -1732,7 +1732,7 @@ class BadCountsConstraint extends RegexConstraint {
|
||||||
|
|
||||||
private static List<String> getMatchesList(int foundCount, String[] matches, List<String> strings) {
|
private static List<String> getMatchesList(int foundCount, String[] matches, List<String> strings) {
|
||||||
List<String> matchesList = new ArrayList<>();
|
List<String> matchesList = new ArrayList<>();
|
||||||
matchesList.add("but found " + foundCount);
|
matchesList.add("Failed comparison: [found] " + foundCount);
|
||||||
if (matches != null) {
|
if (matches != null) {
|
||||||
matchesList.addAll(strings);
|
matchesList.addAll(strings);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
package ir_framework.tests;
|
package ir_framework.tests;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.*;
|
import compiler.lib.ir_framework.*;
|
||||||
import compiler.lib.ir_framework.driver.IRViolationException;
|
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
|
||||||
import compiler.lib.ir_framework.shared.TestRunException;
|
import compiler.lib.ir_framework.shared.TestRunException;
|
||||||
import jdk.test.lib.Asserts;
|
import jdk.test.lib.Asserts;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -24,8 +24,7 @@
|
||||||
package ir_framework.tests;
|
package ir_framework.tests;
|
||||||
|
|
||||||
import compiler.lib.ir_framework.Scenario;
|
import compiler.lib.ir_framework.Scenario;
|
||||||
import compiler.lib.ir_framework.driver.IRMatcher;
|
import compiler.lib.ir_framework.driver.irmatching.IRMatcher;
|
||||||
import compiler.lib.ir_framework.driver.TestVMProcess;
|
|
||||||
import jdk.test.lib.Asserts;
|
import jdk.test.lib.Asserts;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue