8280378: [IR Framework] Support IR matching for different compile phases

Reviewed-by: kvn, rcastanedalo
This commit is contained in:
Christian Hagedorn 2022-11-01 15:41:09 +00:00
parent da0ae5128a
commit f829b5a73f
142 changed files with 7489 additions and 1938 deletions

View file

@ -365,7 +365,7 @@ void PhaseOutput::perform_mach_node_analysis() {
pd_perform_mach_node_analysis();
C->print_method(CompilerPhaseType::PHASE_MACHANALYSIS, 4);
C->print_method(CompilerPhaseType::PHASE_MACH_ANALYSIS, 4);
}
// Convert Nodes to instruction bits and pass off to the VM

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 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
@ -31,14 +31,23 @@
flags(BEFORE_REMOVEUSELESS, "Before RemoveUseless") \
flags(AFTER_PARSING, "After Parsing") \
flags(ITER_GVN1, "Iter GVN 1") \
flags(INCREMENTAL_INLINE_STEP, "Incremental Inline Step") \
flags(INCREMENTAL_INLINE_CLEANUP, "Incremental Inline Cleanup") \
flags(INCREMENTAL_INLINE, "Incremental Inline") \
flags(INCREMENTAL_BOXING_INLINE, "Incremental Boxing Inline") \
flags(EXPAND_VUNBOX, "Expand VectorUnbox") \
flags(SCALARIZE_VBOX, "Scalarize VectorBox") \
flags(INLINE_VECTOR_REBOX, "Inline Vector Rebox Calls") \
flags(EXPAND_VBOX, "Expand VectorBox") \
flags(ELIMINATE_VBOX_ALLOC, "Eliminate VectorBoxAllocate") \
flags(PHASEIDEAL_BEFORE_EA, "PhaseIdealLoop before EA") \
flags(ITER_GVN_AFTER_VECTOR, "Iter GVN after vector box elimination") \
flags(ITER_GVN_BEFORE_EA, "Iter GVN before EA") \
flags(ITER_GVN_AFTER_VECTOR, "Iter GVN after vector box elimination") \
flags(BEFORE_BEAUTIFY_LOOPS, "Before beautify loops") \
flags(AFTER_BEAUTIFY_LOOPS, "After beautify loops") \
flags(BEFORE_CLOOPS, "Before CountedLoop") \
flags(AFTER_CLOOPS, "After CountedLoop") \
flags(PHASEIDEAL_BEFORE_EA, "PhaseIdealLoop before EA") \
flags(AFTER_EA, "After Escape Analysis") \
flags(ITER_GVN_AFTER_EA, "Iter GVN after EA") \
flags(ITER_GVN_AFTER_ELIMINATION, "Iter GVN after eliminating allocations and locks") \
flags(PHASEIDEALLOOP1, "PhaseIdealLoop 1") \
@ -47,24 +56,14 @@
flags(CCP1, "PhaseCCP 1") \
flags(ITER_GVN2, "Iter GVN 2") \
flags(PHASEIDEALLOOP_ITERATIONS, "PhaseIdealLoop iterations") \
flags(OPTIMIZE_FINISHED, "Optimize finished") \
flags(GLOBAL_CODE_MOTION, "Global code motion") \
flags(FINAL_CODE, "Final Code") \
flags(AFTER_EA, "After Escape Analysis") \
flags(BEFORE_CLOOPS, "Before CountedLoop") \
flags(AFTER_CLOOPS, "After CountedLoop") \
flags(BEFORE_BEAUTIFY_LOOPS, "Before beautify loops") \
flags(AFTER_BEAUTIFY_LOOPS, "After beautify loops") \
flags(BEFORE_MATCHING, "Before matching") \
flags(MATCHING, "After matching") \
flags(MACHANALYSIS, "After mach analysis") \
flags(INCREMENTAL_INLINE, "Incremental Inline") \
flags(INCREMENTAL_INLINE_STEP, "Incremental Inline Step") \
flags(INCREMENTAL_INLINE_CLEANUP, "Incremental Inline Cleanup") \
flags(INCREMENTAL_BOXING_INLINE, "Incremental Boxing Inline") \
flags(CALL_CATCH_CLEANUP, "Call catch cleanup") \
flags(MACRO_EXPANSION, "Macro expand") \
flags(BARRIER_EXPANSION, "Barrier expand") \
flags(OPTIMIZE_FINISHED, "Optimize finished") \
flags(BEFORE_MATCHING, "Before matching") \
flags(MATCHING, "After matching") \
flags(GLOBAL_CODE_MOTION, "Global code motion") \
flags(MACH_ANALYSIS, "After mach analysis") \
flags(FINAL_CODE, "Final Code") \
flags(END, "End") \
flags(FAILURE, "Failure") \
flags(ALL, "All") \

View file

@ -69,7 +69,7 @@ public class MaxMinINodeIdealizationTests {
// c0,c1,c2 are constants. x,y,z can be any valid c2 nodes. In this example, x and y are
// RShiftI nodes and z is a ConI.
@Test
@IR(counts = {IRNode.Max_I, "1",
@IR(counts = {IRNode.MAX_I, "1",
IRNode.ADD , "1",
})
public int testMax1(int i) {
@ -78,7 +78,7 @@ public class MaxMinINodeIdealizationTests {
// Similarly, transform min(x + c0, min(y + c1, z)) to min(add(x, c2), z) if x == y, where c2 = MIN2(c0, c1).
@Test
@IR(counts = {IRNode.Min_I, "1",
@IR(counts = {IRNode.MIN_I, "1",
IRNode.ADD , "1",
})
public int testMin1(int i) {
@ -89,7 +89,7 @@ public class MaxMinINodeIdealizationTests {
// c0,c1,c2 are constants. x and y can be any valid c2 nodes. If they are equal, this
// transformation would take place. In this example, x and y are same RShiftI nodes.
@Test
@IR(failOn = {IRNode.Max_I})
@IR(failOn = {IRNode.MAX_I})
@IR(counts = {IRNode.ADD, "1"})
public int testMax2(int i) {
return Math.max((i >> 1) + 10, (i >> 1) + 11);
@ -97,7 +97,7 @@ public class MaxMinINodeIdealizationTests {
// Similarly, transform min(x + c0, y + c1) to add(x, c2) if x == y, where c2 = MIN2(c0, c1).
@Test
@IR(failOn = {IRNode.Min_I})
@IR(failOn = {IRNode.MIN_I})
@IR(counts = {IRNode.ADD, "1"})
public int testMin2(int i) {
return Math.min((i >> 1) + 10, (i >> 1) + 11);
@ -106,13 +106,13 @@ public class MaxMinINodeIdealizationTests {
// Return the same node without generating a MaxINode/MinINode when a node is compared with itself.
// In this test, an integer is being compared with itself but it can be any valid c2 node.
@Test
@IR(failOn = {IRNode.Max_I})
@IR(failOn = {IRNode.MAX_I})
public int testMax3(int i) {
return Math.max(i, i);
}
@Test
@IR(failOn = {IRNode.Min_I})
@IR(failOn = {IRNode.MIN_I})
public int testMin3(int i) {
return Math.min(i, i);
}

View file

@ -39,7 +39,7 @@ public class TestCountedLoopPhiValue {
}
@Test
@IR(counts = { IRNode.COUNTEDLOOP, "1" })
@IR(counts = {IRNode.COUNTED_LOOP, "1" })
@IR(failOn = { IRNode.IF })
public static float test1() {
int i = 0;
@ -64,7 +64,7 @@ public class TestCountedLoopPhiValue {
}
@Test
@IR(counts = { IRNode.COUNTEDLOOP, "1" })
@IR(counts = {IRNode.COUNTED_LOOP, "1" })
@IR(failOn = { IRNode.IF })
public static float test2() {
int i = 0;
@ -89,7 +89,7 @@ public class TestCountedLoopPhiValue {
}
@Test
@IR(counts = { IRNode.COUNTEDLOOP, "1" })
@IR(counts = {IRNode.COUNTED_LOOP, "1" })
@IR(failOn = { IRNode.IF })
public static float test3() {
int i = 10;
@ -114,7 +114,7 @@ public class TestCountedLoopPhiValue {
}
@Test
@IR(counts = { IRNode.COUNTEDLOOP, "1" })
@IR(counts = {IRNode.COUNTED_LOOP, "1" })
@IR(failOn = { IRNode.IF })
public static float test4() {
int i = 10;
@ -144,7 +144,7 @@ public class TestCountedLoopPhiValue {
final static int last_test5_iteration = Integer.MIN_VALUE + Integer.divideUnsigned(test5_limit - Integer.MIN_VALUE, int_stride) * int_stride;
@Test
@IR(counts = { IRNode.COUNTEDLOOP, "1" })
@IR(counts = {IRNode.COUNTED_LOOP, "1" })
@IR(failOn = { IRNode.IF })
public static float test5() {
int i = Integer.MIN_VALUE;
@ -173,7 +173,7 @@ public class TestCountedLoopPhiValue {
final static int last_test6_iteration = Integer.MAX_VALUE - Integer.divideUnsigned(Integer.MAX_VALUE - test6_limit, int_stride) * int_stride;
@Test
@IR(counts = { IRNode.COUNTEDLOOP, "1" })
@IR(counts = {IRNode.COUNTED_LOOP, "1" })
@IR(failOn = { IRNode.IF })
public static float test6() {
int i = Integer.MAX_VALUE;
@ -203,7 +203,7 @@ public class TestCountedLoopPhiValue {
final static long last_test7_iteration = Long.MIN_VALUE + Long.divideUnsigned(test7_limit - Long.MIN_VALUE, long_stride) * long_stride;
@Test
@IR(counts = { IRNode.LONGCOUNTEDLOOP, "1", IRNode.IF, "1" })
@IR(counts = {IRNode.LONG_COUNTED_LOOP, "1", IRNode.IF, "1" })
public static float test7() {
long i = Long.MIN_VALUE;
long j;
@ -231,7 +231,7 @@ public class TestCountedLoopPhiValue {
final static long last_test8_iteration = Long.MAX_VALUE - Long.divideUnsigned(Long.MAX_VALUE - test8_limit, long_stride) * long_stride;
@Test
@IR(counts = { IRNode.LONGCOUNTEDLOOP, "1", IRNode.IF, "1" })
@IR(counts = {IRNode.LONG_COUNTED_LOOP, "1", IRNode.IF, "1" })
public static float test8() {
long i = Long.MAX_VALUE;
long j;

View file

@ -42,10 +42,10 @@ public class TestCountedLoopSafepoint {
}
@Test
@IR(counts = { IRNode.COUNTEDLOOP, "1" })
@IR(applyIf = { "LoopStripMiningIter", "0" }, failOn = { IRNode.SAFEPOINT, IRNode.OUTERSTRIPMINEDLOOP })
@IR(applyIf = { "LoopStripMiningIter", "1" }, counts = { IRNode.SAFEPOINT, "1" }, failOn = { IRNode.OUTERSTRIPMINEDLOOP })
@IR(applyIf = { "LoopStripMiningIter", "> 1" }, counts = { IRNode.SAFEPOINT, "1", IRNode.OUTERSTRIPMINEDLOOP, "1" })
@IR(counts = {IRNode.COUNTED_LOOP, "1" })
@IR(applyIf = { "LoopStripMiningIter", "0" }, failOn = { IRNode.SAFEPOINT, IRNode.OUTER_STRIP_MINED_LOOP})
@IR(applyIf = { "LoopStripMiningIter", "1" }, counts = { IRNode.SAFEPOINT, "1" }, failOn = { IRNode.OUTER_STRIP_MINED_LOOP})
@IR(applyIf = { "LoopStripMiningIter", "> 1" }, counts = {IRNode.SAFEPOINT, "1", IRNode.OUTER_STRIP_MINED_LOOP, "1" })
public static float test(int start, int stop) {
float v = 1;
for (int i = start; i < stop; i++) {

View file

@ -24,7 +24,6 @@
package compiler.c2.irTests;
import compiler.lib.ir_framework.*;
import java.util.Objects;
/*
* @test
@ -42,9 +41,9 @@ public class TestDuplicateBackedge {
}
@Test
@IR(applyIf = { "DuplicateBackedge", "true" }, counts = { IRNode.LOOP, "1", IRNode.COUNTEDLOOP, "1" })
@IR(applyIf = { "DuplicateBackedge", "true" }, counts = {IRNode.LOOP, "1", IRNode.COUNTED_LOOP, "1" })
@IR(applyIf = { "DuplicateBackedge", "false" }, counts = { IRNode.LOOP, "1" })
@IR(applyIf = { "DuplicateBackedge", "false" }, failOn = { IRNode.COUNTEDLOOP })
@IR(applyIf = { "DuplicateBackedge", "false" }, failOn = { IRNode.COUNTED_LOOP})
public static float test() {
float res = 1;
for (int i = 1;;) {

View file

@ -71,97 +71,97 @@ public class TestFPComparison {
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveEqualTwoDoubles(double x, double y) {
return x == y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveEqualTwoFloats(float x, float y) {
return x == y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveNotEqualTwoDoubles(double x, double y) {
return x != y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveNotEqualTwoFloats(float x, float y) {
return x != y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveLessThanTwoDoubles(double x, double y) {
return x < y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveLessThanTwoFloats(float x, float y) {
return x < y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveMoreThanTwoDoubles(double x, double y) {
return x > y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveMoreThanTwoFloats(float x, float y) {
return x > y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveLessEqualTwoDoubles(double x, double y) {
return x <= y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveLessEqualTwoFloats(float x, float y) {
return x <= y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveMoreEqualTwoDoubles(double x, double y) {
return x >= y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveMoreEqualTwoFloats(float x, float y) {
return x >= y ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveEqualOneDouble(double x) {
return x == x ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveEqualOneFloat(float x) {
return x == x ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveNotEqualOneDouble(double x) {
return x != x ? 1 : 0;
}
@Test
@IR(counts = {IRNode.CMOVEI, "1"})
@IR(counts = {IRNode.CMOVE_I, "1"})
public int cMoveNotEqualOneFloat(float x) {
return x != x ? 1 : 0;
}

View file

@ -45,7 +45,7 @@ public class TestFewIterationsCountedLoop {
static final Object object = new Object();
@Test
@IR(failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP })
@IR(failOn = {IRNode.COUNTED_LOOP, IRNode.LOOP })
public static void singleIterationFor() {
for (int i = 0; i < 1; i++) {
barrier = 0x42; // something that can't be optimized out
@ -53,7 +53,7 @@ public class TestFewIterationsCountedLoop {
}
@Test
@IR(failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP })
@IR(failOn = {IRNode.COUNTED_LOOP, IRNode.LOOP })
public static void singleIterationWhile() {
int i = 0;
while (i < 1) {
@ -63,7 +63,7 @@ public class TestFewIterationsCountedLoop {
}
@Test
@IR(failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP })
@IR(failOn = {IRNode.COUNTED_LOOP, IRNode.LOOP })
@Warmup(1) // So C2 can't rely on profile data
public static void singleIterationDoWhile() {
int i = 0;
@ -75,8 +75,8 @@ public class TestFewIterationsCountedLoop {
}
@Test
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP })
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = {IRNode.COUNTED_LOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = {IRNode.COUNTED_LOOP, IRNode.LOOP })
public static void twoIterationsFor() {
for (int i = 0; i < 2; i++) {
barrier = 0x42; // something that can't be optimized out
@ -84,8 +84,8 @@ public class TestFewIterationsCountedLoop {
}
@Test
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP })
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = {IRNode.COUNTED_LOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = {IRNode.COUNTED_LOOP, IRNode.LOOP })
public static void twoIterationsWhile() {
int i = 0;
while (i < 2) {
@ -95,8 +95,8 @@ public class TestFewIterationsCountedLoop {
}
@Test
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP })
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = {IRNode.COUNTED_LOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = {IRNode.COUNTED_LOOP, IRNode.LOOP })
public static void twoIterationsDoWhile() {
int i = 0;
do {
@ -107,8 +107,8 @@ public class TestFewIterationsCountedLoop {
}
@Test
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP })
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = {IRNode.COUNTED_LOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = {IRNode.COUNTED_LOOP, IRNode.LOOP })
public static void threadIterationsFor() {
for (int i = 0; i < 2; i++) {
barrier = 0x42; // something that can't be optimized out
@ -116,8 +116,8 @@ public class TestFewIterationsCountedLoop {
}
@Test
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP })
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = {IRNode.COUNTED_LOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = {IRNode.COUNTED_LOOP, IRNode.LOOP })
public static void threeIterationsWhile() {
int i = 0;
while (i < 2) {
@ -127,8 +127,8 @@ public class TestFewIterationsCountedLoop {
}
@Test
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP })
@IR(applyIf = { "LoopUnrollLimit", "0" }, counts = {IRNode.COUNTED_LOOP, "1" })
@IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = {IRNode.COUNTED_LOOP, IRNode.LOOP })
public static void threeIterationsDoWhile() {
int i = 0;
do {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Red Hat, Inc. All rights reserved.
* Copyright (c) 2021, 2022, Red Hat, Inc. 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
@ -45,7 +45,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1" })
@IR(failOn = { IRNode.COUNTEDLOOP })
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStridePosScalePos(long start, long stop, long length, long offset) {
final long scale = 1;
final long stride = 1;
@ -66,7 +66,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1" })
@IR(failOn = { IRNode.COUNTEDLOOP })
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStridePosScalePosInIntLoop1(int start, int stop, long length, long offset) {
final long scale = 2;
final int stride = 1;
@ -84,7 +84,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1" })
@IR(failOn = { IRNode.COUNTEDLOOP })
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStridePosScalePosInIntLoop2(int start, int stop, long length, long offset) {
final int scale = 2;
final int stride = 1;
@ -102,7 +102,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1"})
@IR(failOn = { IRNode.COUNTEDLOOP})
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStrideNegScaleNeg(long start, long stop, long length, long offset) {
final long scale = -1;
final long stride = 1;
@ -118,7 +118,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1" })
@IR(failOn = { IRNode.COUNTEDLOOP })
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStrideNegScaleNegInIntLoop1(int start, int stop, long length, long offset) {
final long scale = -2;
final int stride = 1;
@ -135,7 +135,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1" })
@IR(failOn = { IRNode.COUNTEDLOOP })
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStrideNegScaleNegInIntLoop2(int start, int stop, long length, long offset) {
final int scale = -2;
final int stride = 1;
@ -152,7 +152,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1"})
@IR(failOn = { IRNode.COUNTEDLOOP})
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStrideNegScalePos(long start, long stop, long length, long offset) {
final long scale = 1;
final long stride = 1;
@ -168,7 +168,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1" })
@IR(failOn = { IRNode.COUNTEDLOOP })
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStrideNegScalePosInIntLoop1(int start, int stop, long length, long offset) {
final long scale = 2;
final int stride = 1;
@ -184,7 +184,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1" })
@IR(failOn = { IRNode.COUNTEDLOOP })
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStrideNegScalePosInIntLoop2(int start, int stop, long length, long offset) {
final int scale = 2;
final int stride = 1;
@ -200,7 +200,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1"})
@IR(failOn = { IRNode.COUNTEDLOOP})
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStridePosScaleNeg(long start, long stop, long length, long offset) {
final long scale = -1;
final long stride = 1;
@ -216,7 +216,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1"})
@IR(failOn = { IRNode.COUNTEDLOOP})
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStridePosScaleNegInIntLoop1(int start, int stop, long length, long offset) {
final long scale = -2;
final int stride = 1;
@ -232,7 +232,7 @@ public class TestLongRangeChecks {
@Test
@IR(counts = { IRNode.LOOP, "1"})
@IR(failOn = { IRNode.COUNTEDLOOP})
@IR(failOn = { IRNode.COUNTED_LOOP})
public static void testStridePosScaleNegInIntLoop2(int start, int stop, long length, long offset) {
final int scale = -2;
final int stride = 1;

View file

@ -24,8 +24,6 @@
package compiler.c2.irTests;
import compiler.lib.ir_framework.*;
import jdk.test.lib.Utils;
import java.util.Random;
/*
* @test
@ -57,7 +55,7 @@ public class TestSkeletonPredicates {
}
@Test
@IR(counts = { IRNode.COUNTEDLOOP, "2" })
@IR(counts = {IRNode.COUNTED_LOOP, "2" })
static double[] test1(int stop) {
double[] array1 = new double[10];
for (int j = 0; j < stop; j++) {

View file

@ -41,7 +41,7 @@ public class TestStripMiningDropsSafepoint {
}
@Test
@IR(applyIf = { "PartialPeelLoop", "true" }, counts = { IRNode.COUNTEDLOOP, "1", IRNode.OUTERSTRIPMINEDLOOP, "1", IRNode.SAFEPOINT, "1" })
@IR(applyIf = { "PartialPeelLoop", "true" }, counts = {IRNode.COUNTED_LOOP, "1", IRNode.OUTER_STRIP_MINED_LOOP, "1", IRNode.SAFEPOINT, "1" })
private static void test1(int[] dst, int[] src) {
// Partial peel is applied. No side effect between exit and
// safepoint.
@ -68,8 +68,8 @@ public class TestStripMiningDropsSafepoint {
}
@Test
@IR(applyIf = { "PartialPeelLoop", "true" }, counts = { IRNode.COUNTEDLOOP, "1", IRNode.SAFEPOINT, "1" })
@IR(applyIf = { "PartialPeelLoop", "true" }, failOn = { IRNode.OUTERSTRIPMINEDLOOP })
@IR(applyIf = { "PartialPeelLoop", "true" }, counts = {IRNode.COUNTED_LOOP, "1", IRNode.SAFEPOINT, "1" })
@IR(applyIf = { "PartialPeelLoop", "true" }, failOn = { IRNode.OUTER_STRIP_MINED_LOOP})
private static void test2(int[] dst, int[] src) {
// Partial peel is applied. Some side effect between exit and
// safepoint.
@ -97,7 +97,7 @@ public class TestStripMiningDropsSafepoint {
}
@Test
@IR(applyIf = { "PartialPeelLoop", "false" }, counts = { IRNode.COUNTEDLOOP, "1", IRNode.OUTERSTRIPMINEDLOOP, "1", IRNode.SAFEPOINT, "1" })
@IR(applyIf = { "PartialPeelLoop", "false" }, counts = {IRNode.COUNTED_LOOP, "1", IRNode.OUTER_STRIP_MINED_LOOP, "1", IRNode.SAFEPOINT, "1" })
private static void test3(int[] dst, int[] src) {
int v = src[0];
for (int i = 0; ; ) {

View file

@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,8 @@ package compiler.c2.irTests;
import jdk.test.lib.Asserts;
import compiler.lib.ir_framework.*;
import static compiler.lib.ir_framework.IRNode.*;
/*
* @test
* @bug 8276162
@ -34,10 +36,6 @@ import compiler.lib.ir_framework.*;
* @run driver compiler.c2.irTests.TestUnsignedComparison
*/
public class TestUnsignedComparison {
private static final String CMP_REGEX = "(\\d+(\\s){2}(" + "Cmp(I|L)" + ".*)+(\\s){2}===.*)";
private static final String CMPU_REGEX = "(\\d+(\\s){2}(" + "Cmp(U|UL)" + ".*)+(\\s){2}===.*)";
private static final String ADD_REGEX = "(\\d+(\\s){2}(" + "Add(I|L)" + ".*)+(\\s){2}===.*)";
private static final int INT_MIN = Integer.MIN_VALUE;
private static final long LONG_MIN = Long.MIN_VALUE;
@ -84,43 +82,43 @@ public class TestUnsignedComparison {
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntVarEQ(int x, int y) {
return x + INT_MIN == y + INT_MIN;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntVarNE(int x, int y) {
return x + INT_MIN != y + INT_MIN;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntVarLT(int x, int y) {
return x + INT_MIN < y + INT_MIN;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntVarLE(int x, int y) {
return x + INT_MIN <= y + INT_MIN;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntVarGT(int x, int y) {
return x + INT_MIN > y + INT_MIN;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntVarGE(int x, int y) {
return x + INT_MIN >= y + INT_MIN;
}
@ -150,43 +148,43 @@ public class TestUnsignedComparison {
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntConEQ(int x) {
return x + INT_MIN == INT_CONST;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntConNE(int x) {
return x + INT_MIN != INT_CONST;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntConLT(int x) {
return x + INT_MIN < INT_CONST;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntConLE(int x) {
return x + INT_MIN <= INT_CONST;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntConGT(int x) {
return x + INT_MIN > INT_CONST;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_I, ADD_I})
@IR(counts = {CMP_U, "1"})
public boolean testIntConGE(int x) {
return x + INT_MIN >= INT_CONST;
}
@ -214,43 +212,43 @@ public class TestUnsignedComparison {
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongVarEQ(long x, long y) {
return x + LONG_MIN == y + LONG_MIN;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongVarNE(long x, long y) {
return x + LONG_MIN != y + LONG_MIN;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongVarLT(long x, long y) {
return x + LONG_MIN < y + LONG_MIN;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongVarLE(long x, long y) {
return x + LONG_MIN <= y + LONG_MIN;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongVarGT(long x, long y) {
return x + LONG_MIN > y + LONG_MIN;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongVarGE(long x, long y) {
return x + LONG_MIN >= y + LONG_MIN;
}
@ -280,43 +278,43 @@ public class TestUnsignedComparison {
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongConEQ(long x) {
return x + LONG_MIN == LONG_CONST;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongConNE(long x) {
return x + LONG_MIN != LONG_CONST;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongConLT(long x) {
return x + LONG_MIN < LONG_CONST;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongConLE(long x) {
return x + LONG_MIN <= LONG_CONST;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongConGT(long x) {
return x + LONG_MIN > LONG_CONST;
}
@Test
@IR(failOn = {CMP_REGEX, ADD_REGEX})
@IR(counts = {CMPU_REGEX, "1"})
@IR(failOn = {CMP_L, ADD_L})
@IR(counts = {CMP_UL, "1"})
public boolean testLongConGE(long x) {
return x + LONG_MIN >= LONG_CONST;
}

View file

@ -95,7 +95,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVEVF, ">0", IRNode.STORE_VECTOR, ">0"})
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVE_VF, ">0", IRNode.STORE_VECTOR, ">0"})
private static void testCMoveVFGT(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (a[i] > b[i]) ? a[i] : b[i];
@ -103,7 +103,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVEVF, ">0", IRNode.STORE_VECTOR, ">0"})
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVE_VF, ">0", IRNode.STORE_VECTOR, ">0"})
private static void testCMoveVFGTSwap(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (b[i] > a[i]) ? a[i] : b[i];
@ -111,7 +111,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVEVF, ">0", IRNode.STORE_VECTOR, ">0"})
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVE_VF, ">0", IRNode.STORE_VECTOR, ">0"})
private static void testCMoveVFLT(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (a[i] < b[i]) ? a[i] : b[i];
@ -119,7 +119,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVEVF, ">0", IRNode.STORE_VECTOR, ">0"})
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVE_VF, ">0", IRNode.STORE_VECTOR, ">0"})
private static void testCMoveVFLTSwap(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (b[i] < a[i]) ? a[i] : b[i];
@ -127,7 +127,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVEVF, ">0", IRNode.STORE_VECTOR, ">0"})
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVE_VF, ">0", IRNode.STORE_VECTOR, ">0"})
private static void testCMoveVFEQ(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (a[i] == b[i]) ? a[i] : b[i];
@ -135,7 +135,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVEVD, ">0", IRNode.STORE_VECTOR, ">0"})
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVE_VD, ">0", IRNode.STORE_VECTOR, ">0"})
private static void testCMoveVDLE(double[] a, double[] b, double[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (a[i] <= b[i]) ? a[i] : b[i];
@ -143,7 +143,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVEVD, ">0", IRNode.STORE_VECTOR, ">0"})
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVE_VD, ">0", IRNode.STORE_VECTOR, ">0"})
private static void testCMoveVDLESwap(double[] a, double[] b, double[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (b[i] <= a[i]) ? a[i] : b[i];
@ -151,7 +151,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVEVD, ">0", IRNode.STORE_VECTOR, ">0"})
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVE_VD, ">0", IRNode.STORE_VECTOR, ">0"})
private static void testCMoveVDGE(double[] a, double[] b, double[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (a[i] >= b[i]) ? a[i] : b[i];
@ -159,7 +159,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVEVD, ">0", IRNode.STORE_VECTOR, ">0"})
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVE_VD, ">0", IRNode.STORE_VECTOR, ">0"})
private static void testCMoveVDGESwap(double[] a, double[] b, double[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (b[i] >= a[i]) ? a[i] : b[i];
@ -167,7 +167,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVEVD, ">0", IRNode.STORE_VECTOR, ">0"})
@IR(counts = {IRNode.LOAD_VECTOR, ">0", IRNode.CMOVE_VD, ">0", IRNode.STORE_VECTOR, ">0"})
private static void testCMoveVDNE(double[] a, double[] b, double[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (a[i] != b[i]) ? a[i] : b[i];
@ -175,7 +175,7 @@ public class TestVectorConditionalMove {
}
@Test
@IR(failOn = {IRNode.CMOVEVD})
@IR(failOn = {IRNode.CMOVE_VD})
private static void testCMoveVDUnsupported() {
int seed = 1001;
for (int i = 0; i < doublec.length; i++) {

View file

@ -40,7 +40,7 @@ public class LoopIdealizationTests {
private void blackhole() { }
@Test
@IR(failOn = {IRNode.MUL, IRNode.DIV, IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.CALL})
@IR(failOn = {IRNode.MUL, IRNode.DIV, IRNode.ADD, IRNode.LOOP, IRNode.COUNTED_LOOP, IRNode.COUNTED_LOOP_MAIN, IRNode.CALL})
// Checks that a for loop with 0 iterations is removed
public void zeroIterForLoop() {
for (int i = 0; i < 0; i++) {
@ -49,7 +49,7 @@ public class LoopIdealizationTests {
}
@Test
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.CALL})
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTED_LOOP, IRNode.COUNTED_LOOP_MAIN, IRNode.CALL})
// Checks that a for loop with 1 iteration doesn't have CountedLoop nodes
public void iterOneBreakForLoop() {
for (int i = 0; i < 500; i++) {
@ -58,7 +58,7 @@ public class LoopIdealizationTests {
}
@Test
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.TRAP})
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTED_LOOP, IRNode.COUNTED_LOOP_MAIN, IRNode.TRAP})
@IR(counts = {IRNode.CALL, "1"})
// Checks that a for loop with 1 iteration is simplified to straight code
public void oneIterForLoop() {
@ -68,7 +68,7 @@ public class LoopIdealizationTests {
}
@Test
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.TRAP})
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTED_LOOP, IRNode.COUNTED_LOOP_MAIN, IRNode.TRAP})
@IR(counts = {IRNode.CALL, "1"})
// Checks that a for loop with 1 iteration is simplified to straight code
public void oneIterForLoop1() {
@ -79,7 +79,7 @@ public class LoopIdealizationTests {
}
@Test
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.TRAP})
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTED_LOOP, IRNode.COUNTED_LOOP_MAIN, IRNode.TRAP})
@IR(counts = {IRNode.CALL, "1"})
// Checks that a for loop with 1 iteration is simplified to straight code
public void oneIterForLoop2() {
@ -107,7 +107,7 @@ public class LoopIdealizationTests {
}
@Test
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.TRAP})
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTED_LOOP, IRNode.COUNTED_LOOP_MAIN, IRNode.TRAP})
@IR(counts = {IRNode.CALL, "1"})
// Checks that a while loop with 1 iteration is simplified to straight code
public void oneIterWhileLoop1() {
@ -119,7 +119,7 @@ public class LoopIdealizationTests {
}
@Test
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.TRAP})
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTED_LOOP, IRNode.COUNTED_LOOP_MAIN, IRNode.TRAP})
@IR(counts = {IRNode.CALL, "1"})
// Checks that a while loop with 1 iteration is simplified to straight code
public void oneIterWhileLoop2() {

View file

@ -52,7 +52,7 @@ public class TestBitShuffleOpers {
//===================== Compress Bits Transforms ================
@Test
@IR(counts = {"RShiftI", " > 0 ", "AndI", " > 0"})
@IR(counts = {IRNode.RSHIFT_I, " > 0 ", IRNode.AND_I, " > 0"})
public void test1(int[] ri, int[] ai, int[] bi) {
for (int i = 0; i < ri.length; i++) {
ri[i] = Integer.compress(ai[i], 1 << bi[i]);
@ -67,7 +67,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"URShiftI", " > 0 "})
@IR(counts = {IRNode.URSHIFT_I, " > 0 "})
public void test2(int[] ri, int[] ai, int[] bi) {
for (int i = 0; i < ri.length; i++) {
ri[i] = Integer.compress(ai[i], -1 << bi[i]);
@ -82,7 +82,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"CompressBits", " > 0 ", "AndI" , " > 0 "})
@IR(counts = {IRNode.COMPRESS_BITS, " > 0 ", IRNode.AND_I , " > 0 "})
public void test3(int[] ri, int[] ai, int[] bi) {
for (int i = 0; i < ri.length; i++) {
ri[i] = Integer.compress(Integer.expand(ai[i], bi[i]), bi[i]);
@ -97,7 +97,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"RShiftL", " > 0 ", "AndL", " > 0"})
@IR(counts = {IRNode.RSHIFT_L, " > 0 ", IRNode.AND_L, " > 0"})
public void test4(long[] rl, long[] al, long[] bl) {
for (int i = 0; i < rl.length; i++) {
rl[i] = Long.compress(al[i], 1L << bl[i]);
@ -112,7 +112,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"URShiftL", " > 0 "})
@IR(counts = {IRNode.URSHIFT_L, " > 0 "})
public void test5(long[] rl, long[] al, long[] bl) {
for (int i = 0; i < rl.length; i++) {
rl[i] = Long.compress(al[i], -1L << bl[i]);
@ -127,7 +127,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"CompressBits", " > 0 ", "AndL" , " > 0 "})
@IR(counts = {IRNode.COMPRESS_BITS, " > 0 ", IRNode.AND_L , " > 0 "})
public void test6(long[] rl, long[] al, long[] bl) {
for (int i = 0; i < rl.length; i++) {
rl[i] = Long.compress(Long.expand(al[i], bl[i]), bl[i]);
@ -142,7 +142,7 @@ public class TestBitShuffleOpers {
}
//===================== Expand Bits Transforms ================
@Test
@IR(counts = {"LShiftI", " > 0 ", "AndI", " > 0"})
@IR(counts = {IRNode.LSHIFT_I, " > 0 ", IRNode.AND_I, " > 0"})
public void test7(int[] ri, int[] ai, int[] bi) {
for (int i = 0; i < ri.length; i++) {
ri[i] = Integer.expand(ai[i], 1 << bi[i]);
@ -157,7 +157,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"LShiftI", " > 0 "})
@IR(counts = {IRNode.LSHIFT_I, " > 0 "})
public void test8(int[] ri, int[] ai, int[] bi) {
for (int i = 0; i < ri.length; i++) {
ri[i] = Integer.expand(ai[i], -1 << bi[i]);
@ -172,7 +172,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"AndI" , " > 0 "})
@IR(counts = {IRNode.AND_I , " > 0 "})
public void test9(int[] ri, int[] ai, int[] bi) {
for (int i = 0; i < ri.length; i++) {
ri[i] = Integer.expand(Integer.compress(ai[i], bi[i]), bi[i]);
@ -187,7 +187,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"LShiftL", " > 0 ", "AndL", " > 0"})
@IR(counts = {IRNode.LSHIFT_L, " > 0 ", IRNode.AND_L, " > 0"})
public void test10(long[] rl, long[] al, long[] bl) {
for (int i = 0; i < rl.length; i++) {
rl[i] = Long.expand(al[i], 1L << bl[i]);
@ -202,7 +202,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"LShiftL", " > 0 "})
@IR(counts = {IRNode.LSHIFT_L, " > 0 "})
public void test11(long[] rl, long[] al, long[] bl) {
for (int i = 0; i < rl.length; i++) {
rl[i] = Long.expand(al[i], -1L << bl[i]);
@ -217,7 +217,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"AndL" , " > 0 "})
@IR(counts = {IRNode.AND_L , " > 0 "})
public void test12(long[] rl, long[] al, long[] bl) {
for (int i = 0; i < rl.length; i++) {
rl[i] = Long.expand(Long.compress(al[i], bl[i]), bl[i]);
@ -234,7 +234,7 @@ public class TestBitShuffleOpers {
// ================ Compress/ExpandBits Vanilla ================= //
@Test
@IR(counts = {"CompressBits", " > 0 "})
@IR(counts = {IRNode.COMPRESS_BITS, " > 0 "})
public void test13(int[] ri, int[] ai, int[] bi) {
for (int i = 0; i < ri.length; i++) {
ri[i] = Integer.compress(ai[i], bi[i]);
@ -250,7 +250,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"CompressBits", " > 0 "})
@IR(counts = {IRNode.COMPRESS_BITS, " > 0 "})
public void test14(long[] rl, long[] al, long[] bl) {
for (int i = 0; i < rl.length; i++) {
rl[i] = Long.compress(al[i], bl[i]);
@ -266,7 +266,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"ExpandBits", " > 0 "})
@IR(counts = {IRNode.EXPAND_BITS, " > 0 "})
public void test15(int[] ri, int[] ai, int[] bi) {
for (int i = 0; i < ri.length; i++) {
ri[i] = Integer.expand(ai[i], bi[i]);
@ -282,7 +282,7 @@ public class TestBitShuffleOpers {
}
@Test
@IR(counts = {"ExpandBits", " > 0 "})
@IR(counts = {IRNode.EXPAND_BITS, " > 0 "})
public void test16(long[] rl, long[] al, long[] bl) {
for (int i = 0; i < rl.length; i++) {
rl[i] = Long.expand(al[i], bl[i]);

View file

@ -40,7 +40,7 @@ public class TestDoubleIsFinite extends TestDoubleClassCheck {
@Test // needs to be run in (fast) debug mode
@Warmup(10000)
@IR(counts = {"IsFiniteD", ">= 1"}) // At least one IsFiniteD node is generated if intrinsic is used
@IR(counts = {IRNode.IS_FINITE_D, ">= 1"}) // At least one IsFiniteD node is generated if intrinsic is used
public void testIsFinite() {
for (int i = 0; i < BUFFER_SIZE; i++) {
outputs[i] = Double.isFinite(inputs[i]);

View file

@ -40,7 +40,7 @@ public class TestDoubleIsInfinite extends TestDoubleClassCheck {
@Test // needs to be run in (fast) debug mode
@Warmup(10000)
@IR(counts = {"IsInfiniteD", ">= 1"}) // At least one IsInfiniteD node is generated if intrinsic is used
@IR(counts = {IRNode.IS_INFINITE_D, ">= 1"}) // At least one IsInfiniteD node is generated if intrinsic is used
public void testIsInfinite() {
for (int i = 0; i < BUFFER_SIZE; i++) {
outputs[i] = Double.isInfinite(inputs[i]);

View file

@ -40,7 +40,7 @@ public class TestFloatIsFinite extends TestFloatClassCheck {
@Test // needs to be run in (fast) debug mode
@Warmup(10000)
@IR(counts = {"IsFiniteF", ">= 1"}) // At least one IsFiniteF node is generated if intrinsic is used
@IR(counts = {IRNode.IS_FINITE_F", ">= 1"}) // At least one IsFiniteF node is generated if intrinsic is used
public void testIsFinite() {
for (int i = 0; i < BUFFER_SIZE; i++) {
outputs[i] = Float.isFinite(inputs[i]);

View file

@ -40,7 +40,7 @@ public class TestFloatIsInfinite extends TestFloatClassCheck {
@Test // needs to be run in (fast) debug mode
@Warmup(10000)
@IR(counts = {"IsInfiniteF", ">= 1"}) // At least one IsInfiniteF node is generated if intrinsic is used
@IR(counts = {IRNode.IS_INFINITE_F, ">= 1"}) // At least one IsInfiniteF node is generated if intrinsic is used
public void testIsInfinite() {
for (int i = 0; i < BUFFER_SIZE; i++) {
outputs[i] = Float.isInfinite(inputs[i]);

View file

@ -73,7 +73,7 @@ public class TestIntegerUnsignedDivMod {
@Test // needs to be run in (fast) debug mode
@Warmup(10000)
@IR(counts = {"UDivI", ">= 1"}) // Atleast one UDivI node is generated if intrinsic is used
@IR(counts = {IRNode.UDIV_I, ">= 1"}) // Atleast one UDivI node is generated if intrinsic is used
public void testDivideUnsigned() {
for (int i = 0; i < BUFFER_SIZE; i++) {
try {
@ -87,7 +87,7 @@ public class TestIntegerUnsignedDivMod {
@Test // needs to be run in (fast) debug mode
@Warmup(10000)
@IR(counts = {"UModI", ">= 1"}) // Atleast one UModI node is generated if intrinsic is used
@IR(counts = {IRNode.UMOD_I, ">= 1"}) // Atleast one UModI node is generated if intrinsic is used
public void testRemainderUnsigned() {
for (int i = 0; i < BUFFER_SIZE; i++) {
try {
@ -102,7 +102,7 @@ public class TestIntegerUnsignedDivMod {
@Test // needs to be run in (fast) debug mode
@Warmup(10000)
@IR(counts = {"UDivModI", ">= 1"}) // Atleast one UDivModI node is generated if intrinsic is used
@IR(counts = {IRNode.UDIV_MOD_I, ">= 1"}) // Atleast one UDivModI node is generated if intrinsic is used
public void testDivModUnsigned() {
for (int i = 0; i < BUFFER_SIZE; i++) {
try {

View file

@ -111,7 +111,7 @@ public class TestLongUnsignedDivMod {
@Test // needs to be run in (fast) debug mode
@Warmup(10000)
@IR(counts = {"UDivL", ">= 1"}) // Atleast one UDivL node is generated if intrinsic is used
@IR(counts = {IRNode.UDIV_L, ">= 1"}) // At least one UDivL node is generated if intrinsic is used
public void testDivideUnsigned() {
for (int i = 0; i < BUFFER_SIZE; i++) {
try {
@ -125,7 +125,7 @@ public class TestLongUnsignedDivMod {
@Test // needs to be run in (fast) debug mode
@Warmup(10000)
@IR(counts = {"UModL", ">= 1"}) // Atleast one UModL node is generated if intrinsic is used
@IR(counts = {IRNode.UMOD_L, ">= 1"}) // At least one UModL node is generated if intrinsic is used
public void testRemainderUnsigned() {
for (int i = 0; i < BUFFER_SIZE; i++) {
try {
@ -140,7 +140,7 @@ public class TestLongUnsignedDivMod {
@Test // needs to be run in (fast) debug mode
@Warmup(10000)
@IR(counts = {"UDivModL", ">= 1"}) // Atleast one UDivModL node is generated if intrinsic is used
@IR(counts = {IRNode.UDIV_MOD_L, ">= 1"}) // Atleast one UDivModL node is generated if intrinsic is used
public void testDivModUnsigned() {
for (int i = 0; i < BUFFER_SIZE; i++) {
try {

View file

@ -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;
import java.util.HashMap;
import java.util.Map;
/**
* This enum represents all available compile phases on which an IR matching can be done. There is a 1:1 mapping
* between IGV phases as specified in phasetype.hpp. Compile phases which are normally not emitted by C2 like FAILURE
* or DEBUG are not listed. This enum should be kept in sync with phasetye.hpp.
*
* <p>
* There are two additional compile phases PRINT_IDEAL and PRINT_OPTO_ASSEMBLY. PRINT_IDEAL is the output that is printed
* when using -XX:+PrintIdeal and PRINT_OPTO_ASSEMBLY when using -XX:+PrintOptoAssembly. For simplicity, these two flags
* are treated as a separated compile phase as well.
*/
public enum CompilePhase {
DEFAULT("For IR node placeholder strings as defined in class IRNode only"),
BEFORE_STRINGOPTS("Before StringOpts"),
AFTER_STRINGOPTS("After StringOpts"),
BEFORE_REMOVEUSELESS("Before RemoveUseless"),
AFTER_PARSING("After Parsing"),
ITER_GVN1("Iter GVN 1"),
INCREMENTAL_INLINE_STEP("Incremental Inline Step"),
INCREMENTAL_INLINE_CLEANUP("Incremental Inline Cleanup"),
INCREMENTAL_INLINE("Incremental Inline"),
INCREMENTAL_BOXING_INLINE("Incremental Boxing Inline"),
EXPAND_VUNBOX("Expand VectorUnbox"),
SCALARIZE_VBOX("Scalarize VectorBox"),
INLINE_VECTOR_REBOX("Inline Vector Rebox Calls"),
EXPAND_VBOX("Expand VectorBox"),
ELIMINATE_VBOX_ALLOC("Eliminate VectorBoxAllocate"),
ITER_GVN_BEFORE_EA("Iter GVN before EA"),
ITER_GVN_AFTER_VECTOR("Iter GVN after vector box elimination"),
BEFORE_BEAUTIFY_LOOPS("Before beautify loops"),
AFTER_BEAUTIFY_LOOPS("After beautify loops"),
// Match on very first BEFORE_CLOOPS phase (there could be multiple phases for multiple loops in the code).
BEFORE_CLOOPS("Before CountedLoop", RegexType.IDEAL_INDEPENDENT, ActionOnRepeat.KEEP_FIRST),
AFTER_CLOOPS("After CountedLoop"),
PHASEIDEAL_BEFORE_EA("PhaseIdealLoop before EA"),
AFTER_EA("After Escape Analysis"),
ITER_GVN_AFTER_EA("Iter GVN after EA"),
ITER_GVN_AFTER_ELIMINATION("Iter GVN after eliminating allocations and locks"),
PHASEIDEALLOOP1("PhaseIdealLoop 1"),
PHASEIDEALLOOP2("PhaseIdealLoop 2"),
PHASEIDEALLOOP3("PhaseIdealLoop 3"),
CCP1("PhaseCCP 1"),
ITER_GVN2("Iter GVN 2"),
PHASEIDEALLOOP_ITERATIONS("PhaseIdealLoop iterations"),
MACRO_EXPANSION("Macro expand"),
BARRIER_EXPANSION("Barrier expand"),
OPTIMIZE_FINISHED("Optimize finished"),
PRINT_IDEAL("PrintIdeal"),
BEFORE_MATCHING("Before matching"),
MATCHING("After matching", RegexType.MACH),
MACH_ANALYSIS("After mach analysis", RegexType.MACH),
GLOBAL_CODE_MOTION("Global code motion", RegexType.MACH),
FINAL_CODE("Final Code", RegexType.MACH),
END("End"),
PRINT_OPTO_ASSEMBLY("PrintOptoAssembly", RegexType.OPTO_ASSEMBLY),
;
private static final Map<String, CompilePhase> PHASES_BY_PARSED_NAME = new HashMap<>();
static {
for (CompilePhase phase : CompilePhase.values()) {
if (phase == PRINT_IDEAL) {
PHASES_BY_PARSED_NAME.put("print_ideal", phase);
} else {
PHASES_BY_PARSED_NAME.put(phase.name(), phase);
}
}
}
private enum ActionOnRepeat {
KEEP_FIRST, KEEP_LAST
}
private final String name;
private final RegexType regexType;
private final ActionOnRepeat actionOnRepeat;
CompilePhase(String name) {
this.name = name;
this.regexType = RegexType.IDEAL_INDEPENDENT;
this.actionOnRepeat = ActionOnRepeat.KEEP_LAST;
}
CompilePhase(String name, RegexType regexType) {
this.name = name;
this.regexType = regexType;
this.actionOnRepeat = ActionOnRepeat.KEEP_LAST;
}
CompilePhase(String name, RegexType regexType, ActionOnRepeat actionOnRepeat) {
this.name = name;
this.regexType = regexType;
this.actionOnRepeat = actionOnRepeat;
}
public String getName() {
return name;
}
public RegexType regexType() {
return regexType;
}
public static CompilePhase forName(String phaseName) {
CompilePhase phase = PHASES_BY_PARSED_NAME.get(phaseName);
TestFramework.check(phase != null, "Could not find phase with name \"" + phaseName + "\"");
return phase;
}
public boolean overrideRepeatedPhase() {
return actionOnRepeat == ActionOnRepeat.KEEP_LAST;
}
}

View file

@ -24,6 +24,7 @@
package compiler.lib.ir_framework;
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
import compiler.lib.ir_framework.shared.TestFormatException;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
@ -84,6 +85,15 @@ public @interface IR {
*/
String[] counts() default {};
/**
* Define a list of {@link CompilePhase} enums to apply the IR rule constraint attributes {@link #failOn()} and/or
* {@link #counts()} on. By default, IR matching is applied on the predefined default phase of an IR node
* placeholder string as defined in {@link IRNode}. For non-IR node constraints (i.e. user-defined regexes with no
* definition in {@link IRNode}), a compile phase must explicitly be set. Otherwise, a {@link TestFormatException}
* is reported.
*/
CompilePhase[] phase() default { CompilePhase.DEFAULT };
/**
* Define a single VM flag precondition which <i>must hold</i> when applying the IR rule. If the VM flag precondition
* fails, then the IR rule is not applied. This is useful if a commonly used flag alters the IR in such a way that an IR rule

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
# IR Test Framework
This folder contains a test framework whose main purpose is to perform regex-based checks on the C2 IR shape of test methods emitted by the VM flags _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_. The framework can also be used for other non-IR matching (and non-compiler) tests by providing easy to use annotations for commonly used testing patterns and compiler control flags.
This folder contains a test framework whose main purpose is to perform regex-based checks on the C2 IR shape of test methods emitted by the VM flags `-XX:+PrintIdeal`, `-XX:CompileCommand=PrintIdealPhase` and/or `-XX:+PrintOptoAssembly`. The framework can also be used for other non-IR matching (and non-compiler) tests by providing easy to use annotations for commonly used testing patterns and compiler control flags.
## 1. How to Use the Framework
The framework is intended to be used in JTreg tests. The JTreg header of the test must contain `@library /test/lib /` (2 paths) and should be run as a driver with `@run driver`. Annotate the test code with the supported framework annotations and call the framework from within the test's `main()` method. A simple example is shown below:
@ -51,22 +51,61 @@ Neither the base nor the checked tests provide any control over how a `@Test` an
More information on checked tests with a precise definition can be found in the Javadocs of [Run](./Run.java). Concrete examples on how to specify a custom run test can be found in [CustomRunTestsExample](../../../testlibrary_tests/ir_framework/examples/CustomRunTestExample.java).
### 2.2 IR Verification
The main feature of this framework is to perform a simple but yet powerful regex-based C2 IR matching on the output of _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_. For simplicity, we will refer to the "IR" or "IR matching" when actually meaning the combined output of _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_ for a C2 compilation.
The main feature of this framework is to perform a simple but yet powerful regex-based C2 IR matching on the output of `-XX:+PrintIdeal`, `-XX:+PrintOptoAssembly` and/or on specific compile phases emitted by the compile command `-XX:CompileCommand=PrintIdealPhase` which supports the same set of compile phases as the Ideal Graph Visualizer (IGV).
The user has the possibility to add an additional `@IR` annotation to any `@Test` annotated method (regardless of the kind of test mentioned in section 2.1) to specify a constraint/rule on the compiled IR shape. The `@IR` annotation provides two kinds of regex checks:
The user has the possibility to add one or more `@IR` annotations to any `@Test` annotated method (regardless of the kind of test mentioned in section 2.1) to specify regex constraints/rules on the compiled IR shape of any compile phase (for simplicity, the framework treats the output of `-XX:+PrintIdeal` and `-XX:+PrintOptoAssembly` as a separate compile phase next to the compile phases emitted by `-XX:CompileCommand=PrintIdealPhase`).
- A `failOn` check that verifies that the provided regex is not matched in the C2 IR.
- A `counts` check that verifies that the provided regex is matched a user defined number of times in the C2 IR.
#### Pre-defined Regexes for IR Nodes
To perform a matching on a C2 IR node, the user can directly use the `public static final` strings defined in class [IRNode](./IRNode.java) which mostly represent either a real IR node or group of IR nodes as found in the C2 compiler as node classes (there are rare exceptions). These strings represent special placeholder strings (referred to as "IR placeholder string" or just "IR node") which are replaced by the framework by regexes depending on which compile phases (defined with attribute `phase` in [@IR](./IR.java)) the IR rule should be applied on. If an IR node placeholder string cannot be used for a specific compile phase (e.g. the IR node does not exist in this phase), a format violation will be reported.
A regex can either be a custom string or any of the default regexes provided by the framework in [IRNode](./IRNode.java) for some commonly used IR nodes (also provides the possibility of composite regexes).
The exact mapping from an IR node placeholder string to regexes for different compile phases together with a default phase (see next section) is defined in a static block directly below the corresponding IR node placeholder string in [IRNode](./IRNode.java).
An IR verification cannot always be performed. For example, a JTreg test could be run with _-Xint_ or not a debug build (_-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_ are debug build flags). But also CI tier testing could add additional JTreg VM and Javaoptions flags which could make an IR rule unstable.
#### Composite IR Nodes
There are also special composite IR node placeholder strings which expect an additional user defined string which are then inserted in the final regex. For example, `IRNode.STORE_OF_FIELD` matches any store to the user defined field name. In the following `@IR` rule, we fail because we have a store to `iFld`:
In general, the framework will only perform IR verification if the used VM flags allow a C2 compilation and if non-critical additional JTreg VM and Javaoptions are provided (see whiteflag list in [TestFramework](./TestFramework.java)). The user test code, however, can specify any flags which still allow an IR verification to be performed if a C2 compilation is done (expected flags by user defined `@IR` annotations).
```
@Test
@IR(failOn = {IRNode.STORE_OF_FIELD, "iFld"})
public void test() {
iFld = 34;
}
```
An `@IR` annotation allows additional preconditions/restrictions on the currently present VM flags to enable or disable rules when certain flags are present or have a specific value (see `applyIfXX` properties of an `@IR` annotation). If a `@Test` annotated method has multiple preconditions (for example `applyIf` and `applyIfCPUFeature`), they are evaluated as a logical conjunction.
#### User-defined Regexes
More information about IR matching can be found in the Javadocs of [IR](./IR.java). Concrete examples on how to specify IR constraint/rules can be found in [IRExample](../../../testlibrary_tests/ir_framework/examples/IRExample.java) and [TestIRMatching](../../../testlibrary_tests/ir_framework/tests/TestIRMatching.java) (an internal framework test).
The user can also directly specify user-defined regexes in combination with a required compile phase (there is no default compile phase known by the framework for custom regexes). If such a user-defined regex represents a not yet supported C2 IR node, it is highly encouraged to directly add a new IR node placeholder string definition to [IRNode](./IRNode.java) for it instead together with a static regex mapping block.
#### Default Compile Phase
When not specifying any compile phase with `phase` in [@IR](./IR.java) (or explicitly setting `CompilePhase.DEFAULT`), the framework will perform IR matching on a default compile phase which for most IR nodes is `CompilePhase.PRINT_IDEAL` (output of flag `-XX:+PrintIdeal`, the state of the machine independent ideal graph after applying optimizations). The default phase for each IR node is defined in the static regex mapping block below each IR node placeholder string in [IRNode](./IRNode.java).
#### Two Kinds of IR Checks
The [@IR](./IR.java) annotation provides two kinds of checks:
- `failOn`: A list of one or more IR nodes/user-defined regexes which are not allowed to occur in any compilation output of any compile phase.
- `counts`: A list of one or more "IR node/user-defined regex - counter" pairs which specify how often each IR node/user-defined regex should be matched on the compilation output of each compile phase.
#### Disable/Enable IR Rules based on VM Flags
One might also want to restrict the application of certain `@IR` rules depending on the used flags in the test VM. These could be flags defined by the user or by JTreg. In the latter case, the flags must be whitelisted in `JTREG_WHITE_LIST_FLAGS` in [TestFramework](./TestFramework.java) (i.e. have no unexpected impact on the IR except if the flag simulates a specific machine setup like `UseAVX={1,2,3}` etc.) to enable an IR verification by the framework. The `@IR` rules thus have an option to restrict their application:
- `applyIf`: Only apply a rule if a flag has the specified value/range of values.
- `applyIfNot`: Only apply a rule if a flag has **not** a specified value/range of values
(inverse of `applyIf`).
- `applyIfAnd`: Only apply a rule if **all** flags have the specified value/range of values.
- `applyIfOr`: Only apply a rule if **at least one** flag has the specified value/range of values.
#### Disable/Enable IR Rules based on available CPU Features
Sometimes, an `@IR` rule should only be applied if a certain CPU feature is present. This can be done with
the attributes `applyIfCPUFeatureXXX` in [@IR](./IR.java) which follow the same logic as the `applyIfXXX` methods for flags in the previous section. If a `@Test` annotated method has multiple preconditions (for example `applyIf` and `applyIfCPUFeature`), they are evaluated as a logical conjunction. An example with `applyIfCPUFeatureXXX` can be found in [TestCPUFeatureCheck](../../../testlibrary_tests/ir_framework/tests/TestCPUFeatureCheck.java) (internal framework test).
#### Implicitly Skipping IR Verification
An IR verification cannot always be performed. Certain VM flags explicitly disable IR verification, change the IR shape in unexpected ways letting IR rules fail or even make IR verification impossible:
- `-DVerifyIR=false` is used
- The test is run with a non-debug build.
- `-Xcomp`, `-Xint`, `-XX:-UseCompile`, `-XX:CompileThreshold`, `-DFlipC1C2=true`, or `-DExcludeRandom=true` are used.
- JTreg specifies non-whitelisted flags as VM and/or Javaoptions (could change the IR in unexpected ways).
More information about IR matching can be found in the Javadocs of [IR](./IR.java). Concrete examples on how to specify IR constraint/rules can be found in [IRExample](../../../testlibrary_tests/ir_framework/examples/IRExample.java), [TestIRMatching](../../../testlibrary_tests/ir_framework/tests/TestIRMatching.java) (internal framework test), and [TestPhaseIRMatching](../../../testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java) (internal framework test).
### 2.3 Test VM Flags and Scenarios
The recommended way to use the framework is by defining a single `@run driver` statement in the JTreg header which, however, does not allow the specification of additional test VM flags. Instead, the user has the possibility to provide VM flags by calling `TestFramework.runWithFlags()` or by creating a `TestFramework` builder object on which `addFlags()` can be called.

View file

@ -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;
/**
* Enum to denote the regex type of the associated {@link CompilePhase}.
*
* @see CompilePhase
*/
public enum RegexType {
IDEAL_INDEPENDENT, MACH, OPTO_ASSEMBLY
}

View file

@ -28,6 +28,8 @@ import compiler.lib.ir_framework.driver.TestVMException;
import compiler.lib.ir_framework.driver.TestVMProcess;
import compiler.lib.ir_framework.driver.irmatching.IRMatcher;
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.parser.MethodCompilationParser;
import compiler.lib.ir_framework.shared.*;
import compiler.lib.ir_framework.test.TestVM;
import jdk.test.lib.Platform;
@ -105,6 +107,7 @@ public class TestFramework {
* performed when all these additional JTreg flags (does not include additionally added framework and scenario flags
* by user code) are whitelisted.
*
* <p>
* A flag is whitelisted if it is a property flag (starting with -D), -ea, -esa, or if the flag name contains any of
* the entries of this list as a substring (partial match).
*/
@ -301,8 +304,8 @@ public class TestFramework {
* @return the same framework instance.
*/
public TestFramework addScenarios(Scenario... scenarios) {
TestFormat.check(scenarios != null && Arrays.stream(scenarios).noneMatch(Objects::isNull),
"A scenario cannot be null");
TestFormat.checkAndReport(scenarios != null && Arrays.stream(scenarios).noneMatch(Objects::isNull),
"A scenario cannot be null");
if (this.scenarios == null) {
this.scenarios = new ArrayList<>();
this.scenarioIndices = new HashSet<>();
@ -310,10 +313,11 @@ public class TestFramework {
for (Scenario scenario : scenarios) {
int scenarioIndex = scenario.getIndex();
TestFormat.check(scenarioIndices.add(scenarioIndex),
TestFormat.checkNoThrow(scenarioIndices.add(scenarioIndex),
"Cannot define two scenarios with the same index " + scenarioIndex);
this.scenarios.add(scenario);
}
TestFormat.throwIfAnyFailures();
return this;
}
@ -325,6 +329,7 @@ public class TestFramework {
if (shouldInstallWhiteBox()) {
installWhiteBox();
}
checkIRRuleCompilePhasesFormat();
disableIRVerificationIfNotFeasible();
if (scenarios == null) {
@ -334,7 +339,6 @@ public class TestFramework {
System.err.println(System.lineSeparator() + e.getExceptionInfo() + RERUN_HINT);
throw e;
} catch (IRViolationException e) {
System.out.println("Compilation(s) of failed match(es):");
System.out.println(e.getCompilations());
System.err.println(System.lineSeparator() + e.getExceptionInfo() + System.lineSeparator() + RERUN_HINT);
throw e;
@ -344,6 +348,17 @@ public class TestFramework {
}
}
private void checkIRRuleCompilePhasesFormat() {
for (Method method : testClass.getDeclaredMethods()) {
for (IR irAnno : method.getAnnotationsByType(IR.class)) {
TestFormat.checkNoThrow(irAnno.phase().length > 0,
"@IR rule " + irAnno + " must specify a non-empty list of compile " +
"phases \"phase\" at " + method);
}
}
TestFormat.throwIfAnyFailures();
}
/**
* Try to load the Whitebox class from the user directory with a custom class loader. If the user has already built the
* Whitebox, we can load it. Otherwise, the framework needs to install it.
@ -375,7 +390,7 @@ public class TestFramework {
* @return the same framework instance.
*/
public TestFramework setDefaultWarmup(int defaultWarmup) {
TestFormat.check(defaultWarmup >= 0, "Cannot specify a negative default warm-up");
TestFormat.checkAndReport(defaultWarmup >= 0, "Cannot specify a negative default warm-up");
this.defaultWarmup = defaultWarmup;
return this;
}
@ -625,8 +640,9 @@ public class TestFramework {
}
if (e instanceof IRViolationException irException) {
// For IR violations, only show the actual violations and not the (uninteresting) stack trace.
System.out.println((scenario != null ? "Scenario #" + scenario.getIndex() + " - " : "")
+ "Compilation(s) of failed matche(s):");
if (scenario != null) {
System.out.println("Scenario #" + scenario.getIndex());
}
System.out.println(irException.getCompilations());
builder.append(errorMsg).append(System.lineSeparator()).append(irException.getExceptionInfo());
} else if (e instanceof TestVMException testVMException) {
@ -708,7 +724,7 @@ public class TestFramework {
}
private boolean hasIRAnnotations() {
return Arrays.stream(testClass.getDeclaredMethods()).anyMatch(m -> m.getAnnotationsByType(IR.class) != null);
return Arrays.stream(testClass.getDeclaredMethods()).anyMatch(m -> m.getAnnotationsByType(IR.class).length > 0);
}
private boolean onlyWhitelistedJTregVMAndJavaOptsFlags() {
@ -729,7 +745,11 @@ public class TestFramework {
TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup);
if (shouldVerifyIR) {
try {
new IRMatcher(testVMProcess.getHotspotPidFileName(), testVMProcess.getIrEncoding(), testClass);
MethodCompilationParser methodCompilationParser = new MethodCompilationParser(testClass);
Matchable testClassMatchable = methodCompilationParser.parse(testVMProcess.getHotspotPidFileName(),
testVMProcess.getIrEncoding());
IRMatcher matcher = new IRMatcher(testClassMatchable);
matcher.match();
} catch (IRViolationException e) {
e.addCommandLine(testVMProcess.getCommandLine());
throw e;

View file

@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@ -117,7 +117,7 @@ public class FlagVMProcess {
throw new TestRunException("Failed to execute TestFramework flag VM", e);
}
testVMFlagsFile = FlagVM.TEST_VM_FLAGS_FILE_PREFIX + oa.pid()
+ FlagVM.TEST_VM_FLAGS_FILE_POSTFIX;
+ FlagVM.FILE_POSTFIX;
checkFlagVMExitCode();
}

View file

@ -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.driver.irmatching;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
import java.util.Map;
/**
* This class provides information about the compilation output of a compile phase for an {@link IRMethod}.
*/
public class Compilation {
private final Map<CompilePhase, String> compilationOutputMap;
public Compilation(Map<CompilePhase, String> compilationOutputMap) {
this.compilationOutputMap = compilationOutputMap;
}
/**
* Is there a compilation output for {@code compilePhase}?
*/
public boolean hasOutput(CompilePhase compilePhase) {
return compilationOutputMap.containsKey(compilePhase);
}
/**
* Get the compilation output for non-default compile phase {@code phase} or an empty string if no output was found
* in the hotspot_pid* file for this compile phase.
*/
public String output(CompilePhase compilePhase) {
TestFramework.check(compilePhase != CompilePhase.DEFAULT, "cannot query for DEFAULT");
return compilationOutputMap.getOrDefault(compilePhase, "");
}
}

View file

@ -23,69 +23,50 @@
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.*;
import compiler.lib.ir_framework.driver.irmatching.parser.MethodCompilationParser;
import compiler.lib.ir_framework.driver.irmatching.report.CompilationOutputBuilder;
import compiler.lib.ir_framework.driver.irmatching.report.FailureMessageBuilder;
/**
* This class parses the hotspot_pid* file of the test VM to match all applicable @IR rules afterwards.
* This class performs IR matching on the prepared {@link TestClass} object parsed by {@link MethodCompilationParser}.
* All applicable @IR rules are matched with all their defined compilation phases. If there are any IR matching failures,
* an {@link IRViolationException} is reported which provides a formatted failure message and the compilation outputs
* of the failed compilation phases.
*/
public class IRMatcher {
public static final String SAFEPOINT_WHILE_PRINTING_MESSAGE = "<!-- safepoint while printing -->";
private final Matchable testClass;
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);
}
public IRMatcher(Matchable testClass) {
this.testClass = testClass;
}
/**
* Do an IR matching of all methods with applicable @IR rules prepared with by the {@link IRMethodParser}.
* Do an IR matching of all methods with applicable @IR rules prepared with by the {@link MethodCompilationParser}.
*/
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();
public void match() {
MatchResult result = testClass.match();
if (result.fail()) {
results.add(result);
reportFailures(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 by throwing an {@link IRViolationException}. This includes
* an exact description of the failure (method, rule, compile phase, check attribute, and constraint) and the
* associated compile phase output of the failure.
*/
private void reportFailures(MatchResult result) {
String failureMsg = new FailureMessageBuilder(result).build();
String compilationOutput = new CompilationOutputBuilder(result).build();
throwIfNoSafepointWhilePrinting(failureMsg, compilationOutput);
}
/**
* 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.
* In some very rare cases, the hotspot_pid* file to IR 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 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);

View file

@ -1,81 +0,0 @@
/*
* 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();
}
}

View file

@ -23,18 +23,24 @@
package compiler.lib.ir_framework.driver.irmatching;
import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
/**
* 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}.
* This interface is implemented by all classes which represent an IR match result of a {@link Matchable} class.
* A match result class accepts a {@link MatchResultVisitor} to visit the result (i.e. for reporting etc.).
* The visitor is responsible to call {@link #accept(MatchResultVisitor)} of the children match results by using
* {@link AcceptChildren#accept(MatchResultVisitor)}.
*/
public interface MatchResult {
/**
* Does this match result represent a failure?
* Does this match result represent an IR match failure?
*/
boolean fail();
/**
* Builds a failure message in a pretty format to be used by the IR matching failure reporting.
* Allow a {@link MatchResultVisitor} to visit the match result which in turn invokes the visit methods of the
* visitor.
*/
String buildFailureMessage();
void accept(MatchResultVisitor visitor);
}

View file

@ -23,28 +23,12 @@
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
* This interface is implemented by all classes on which an IR matching request can be performed.
*/
public enum OutputMatch {
public interface Matchable {
/**
* There was no compilation output. Should not happen and results in a failure.
* Apply matching on this IR matching entity class.
*/
NONE,
/**
* Matched on PrintIdeal.
*/
IDEAL,
/**
* Matched on PrintOptoAssembly.
*/
OPTO_ASSEMBLY,
/**
* Matched on PrintIdeal and PrintOptoAssembly.
*/
BOTH
MatchResult match();
}

View file

@ -23,28 +23,29 @@
package compiler.lib.ir_framework.driver.irmatching;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchResult;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Class to build the compilation output of IR matching failures.
*
* @see IRMethodMatchResult
* This class performs matching on a collection of {@link Matchable} objects. It returns a list of {@link MatchResult}
* objects which failed or an empty list of there was not failure.
*/
class CompilationOutputBuilder {
public class MatchableMatcher {
private final Collection<? extends Matchable> matchables;
public static String build(List<IRMethodMatchResult> results) {
StringBuilder compilationsBuilder = new StringBuilder();
for (IRMethodMatchResult result : results) {
if (result.fail()) {
compilationsBuilder.append(buildMatchedCompilationMessage(result));
public MatchableMatcher(Collection<? extends Matchable> matchables) {
this.matchables = matchables;
}
public List<MatchResult> match() {
List<MatchResult> results = new ArrayList<>();
for (Matchable matchable : matchables) {
MatchResult matchResult = matchable.match();
if (matchResult.fail()) {
results.add(matchResult);
}
}
return compilationsBuilder.toString();
}
private static String buildMatchedCompilationMessage(IRMethodMatchResult result) {
return result.getMatchedCompilationOutput() + System.lineSeparator() + System.lineSeparator();
return results;
}
}

View file

@ -21,25 +21,19 @@
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.irrule;
package compiler.lib.ir_framework.driver.irmatching;
import compiler.lib.ir_framework.IR;
import java.util.List;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.SuccessResult;
/**
* Class representing a result of an applied failOn attribute of an IR rule.
*
* @see IR#failOn()
* Test class that does not contain any applicable {@link IR @IR} annotations and therefore does not fail. It simply
* returns a {@link SuccessResult} object when being matched.
*/
class FailOnMatchResult extends CheckAttributeMatchResult {
public void setFailures(List<RegexFailure> regexFailures) {
this.regexFailures = regexFailures;
}
public class NonIRTestClass implements Matchable {
@Override
public String buildFailureMessage() {
return " - failOn: Graph contains forbidden nodes:" + System.lineSeparator()
+ collectRegexFailureMessages();
public MatchResult match() {
return SuccessResult.getInstance();
}
}

View file

@ -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;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.Test;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchable;
import java.util.SortedSet;
/**
* This class represents the user defined test class with which the IR framework was started (the class containing all
* the {@link Test @Test}/{@link IR @IR} annotated methods).
*
* @see Test
* @see IRMethod
* @see TestClassMatchResult
*/
public class TestClass implements Matchable {
private final MatchableMatcher matcher;
public TestClass(SortedSet<IRMethodMatchable> irMethods) {
TestFramework.check(!irMethods.isEmpty(), "must not be empty");
this.matcher = new MatchableMatcher(irMethods);
}
@Override
public MatchResult match() {
return new TestClassMatchResult(matcher.match());
}
}

View file

@ -0,0 +1,55 @@
/*
* 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.visitor.AcceptChildren;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
import java.util.List;
/**
* This class represents a matching result of a {@link TestClass}. It contains all IR method results, sorted by
* method names.
*
* @see TestClass
*/
public class TestClassMatchResult implements MatchResult {
private final AcceptChildren acceptChildren;
private final boolean failed;
public TestClassMatchResult(List<MatchResult> matchResults) {
this.acceptChildren = new AcceptChildren(matchResults);
this.failed = !matchResults.isEmpty();
}
@Override
public boolean fail() {
return failed;
}
@Override
public void accept(MatchResultVisitor visitor) {
visitor.visitTestClass(acceptChildren);
}
}

View file

@ -23,94 +23,65 @@
package compiler.lib.ir_framework.driver.irmatching.irmethod;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.Test;
import compiler.lib.ir_framework.driver.irmatching.Compilation;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.MatchableMatcher;
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRule;
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
import compiler.lib.ir_framework.shared.TestFormat;
import compiler.lib.ir_framework.shared.TestFormatException;
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.
* This class represents a {@link Test @Test} annotated method that has an associated non-empty list of applicable
* {@link IR @IR} rules.
*
* @see IR
* @see IRRule
* @see IRMethodMatchResult
*/
public class IRMethod {
public class IRMethod implements IRMethodMatchable {
private final Method method;
private final List<IRRule> irRules;
private final StringBuilder outputBuilder;
private String output;
private String idealOutput;
private String optoAssemblyOutput;
private final MatchableMatcher matcher;
public IRMethod(Method method, int[] ruleIds, IR[] irAnnos) {
public IRMethod(Method method, int[] ruleIds, IR[] irAnnos, Compilation compilation) {
this.method = method;
this.irRules = new ArrayList<>();
for (int i : ruleIds) {
irRules.add(new IRRule(this, i, irAnnos[i - 1]));
}
this.outputBuilder = new StringBuilder();
this.output = "";
this.idealOutput = "";
this.optoAssemblyOutput = "";
this.matcher = new MatchableMatcher(createIRRules(method, ruleIds, irAnnos, compilation));
}
public Method getMethod() {
return method;
}
/**
* The Ideal output comes always before the Opto Assembly output. We might parse multiple C2 compilations of this method.
* Only keep the very last one by overriding 'output'.
*/
public void setIdealOutput(String idealOutput) {
outputBuilder.setLength(0);
this.idealOutput = "PrintIdeal:" + System.lineSeparator() + idealOutput;
outputBuilder.append(this.idealOutput);
}
/**
* The Opto Assembly output comes after the Ideal output. Simply append to 'output'.
*/
public void setOptoAssemblyOutput(String optoAssemblyOutput) {
this.optoAssemblyOutput = "PrintOptoAssembly:" + System.lineSeparator() + optoAssemblyOutput;
outputBuilder.append(System.lineSeparator()).append(System.lineSeparator()).append(this.optoAssemblyOutput);
output = outputBuilder.toString();
}
public String getOutput() {
return output;
}
public String getIdealOutput() {
return idealOutput;
}
public String getOptoAssemblyOutput() {
return optoAssemblyOutput;
}
/**
* Apply all IR rules of this IR method.
*/
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());
}
}
private NormalMatchResult getNormalMatchResult(List<IRRuleMatchResult> results) {
for (IRRule irRule : irRules) {
IRRuleMatchResult result = irRule.applyCheckAttribute();
if (result.fail()) {
results.add(result);
private List<Matchable> createIRRules(Method method, int[] ruleIds, IR[] irAnnos, Compilation compilation) {
List<Matchable> irRules = new ArrayList<>();
for (int ruleId : ruleIds) {
try {
irRules.add(new IRRule(ruleId, irAnnos[ruleId - 1], compilation));
} catch (TestFormatException e) {
String postfixErrorMsg = " for IR rule " + ruleId + " at " + method + ".";
TestFormat.failNoThrow(e.getMessage() + postfixErrorMsg);
}
}
return new NormalMatchResult(this, results);
return irRules;
}
/**
* Used only for sorting.
*/
@Override
public String name() {
return method.getName();
}
/**
* Apply all IR rules of this method for each of the specified (or implied in case of
* {@link CompilePhase#DEFAULT}) compile phases.
*/
@Override
public MatchResult match() {
return new IRMethodMatchResult(method, matcher.match());
}
}

View file

@ -24,30 +24,38 @@
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;
import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
import java.lang.reflect.Method;
import java.util.List;
/**
* This base class represents an IR matching result of all IR rules of a method.
* This class represents a matching result of an {@link IRMethod}. It contains a list of all IR rule match results
* which could have been applied on different compile phases.
*
* @see IRRuleMatchResult
* @see IRMethod
*/
abstract public class IRMethodMatchResult implements Comparable<IRMethodMatchResult>, MatchResult {
protected final IRMethod irMethod;
public class IRMethodMatchResult implements MatchResult {
private final AcceptChildren acceptChildren;
private final boolean failed;
private final Method method;
private final int failedIRRules;
IRMethodMatchResult(IRMethod irMethod) {
this.irMethod = irMethod;
public IRMethodMatchResult(Method method, List<MatchResult> matchResults) {
this.acceptChildren = new AcceptChildren(matchResults);
this.failed = !matchResults.isEmpty();
this.method = method;
this.failedIRRules = matchResults.size();
}
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());
public boolean fail() {
return failed;
}
@Override
public void accept(MatchResultVisitor visitor) {
visitor.visitIRMethod(acceptChildren, method, failedIRRules);
}
}

View file

@ -0,0 +1,44 @@
/*
* 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.Matchable;
/**
* Interface for all matchable objects related to IR methods. These objects are sorted by the method name.
*
* @see IRMethod
* @see NotCompiledIRMethod
*/
public interface IRMethodMatchable extends Matchable, Comparable<IRMethodMatchable> {
String name();
/**
* Sort by method name.
*/
@Override
default int compareTo(IRMethodMatchable other) {
return this.name().compareTo(other.name());
}
}

View file

@ -1,77 +0,0 @@
/*
* 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();
}
}

View file

@ -1,64 +0,0 @@
/*
* 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();
}
}

View file

@ -1,67 +0,0 @@
/*
* 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();
}
}

View file

@ -0,0 +1,60 @@
/*
* 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.irmethod;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.Run;
import compiler.lib.ir_framework.RunMode;
import java.lang.reflect.Method;
/**
* This class represents a special IR method which was not compiled by the IR framework. This could happen when a
* method is not invoked enough times by a {@link Run @Run} method in {@link RunMode#STANDALONE} mode to be C2 compiled.
*
* @see IR
* @see Run
*/
public class NotCompiledIRMethod implements IRMethodMatchable {
private final Method method;
private final int ruleCount;
public NotCompiledIRMethod(Method method, int ruleCount) {
this.method = method;
this.ruleCount = ruleCount;
}
@Override
public String name() {
return method.getName();
}
/**
* Directly return a {@link NotCompiledIRMethodMatchResult} as we do not need to match IR rules individually.
*/
@Override
public NotCompiledIRMethodMatchResult match() {
return new NotCompiledIRMethodMatchResult(method, ruleCount);
}
}

View file

@ -23,22 +23,27 @@
package compiler.lib.ir_framework.driver.irmatching.irmethod;
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
import compiler.lib.ir_framework.Run;
import compiler.lib.ir_framework.RunMode;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
import java.lang.reflect.Method;
/**
* This class represents an IR matching result where the compilation output was empty.
* This class represents a special matching result of an IR method where the compilation output was completely empty.
* This could happen when using {@link RunMode#STANDALONE} in a {@link Run @Run} method.
*
* @see IRRuleMatchResult
* @see IRMethod
* @see NotCompiledIRMethod
* @see Run
*/
public class MissingCompilationResult extends IRMethodMatchResult {
public class NotCompiledIRMethodMatchResult implements MatchResult {
private final Method method;
private final int failedIRRules;
private final MissingCompilationMessageBuilder failureMessageBuilder;
MissingCompilationResult(IRMethod irMethod, int failedIRRules) {
super(irMethod);
public NotCompiledIRMethodMatchResult(Method method, int failedIRRules) {
this.method = method;
this.failedIRRules = failedIRRules;
this.failureMessageBuilder = new MissingCompilationMessageBuilder(irMethod);
}
@Override
@ -47,22 +52,8 @@ public class MissingCompilationResult extends IRMethodMatchResult {
}
@Override
public String getMatchedCompilationOutput() {
return "<empty>";
public void accept(MatchResultVisitor visitor) {
visitor.visitMethodNotCompiled(method, failedIRRules);
}
@Override
public String buildFailureMessage() {
return failureMessageBuilder.build();
}
private String getMethodLine() {
return " Method \"" + irMethod.getMethod() + "\":" + System.lineSeparator();
}
@Override
public int getFailedIRRuleCount() {
return failedIRRules;
}
}

View file

@ -1,116 +0,0 @@
/*
* 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.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 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<Integer> 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<Integer> parseComparison(IRRule irRule, String node, String constraint) {
String postfixErrorMsg = "in count constraint " + getPostfixErrorMsg(irRule, node);
return ComparisonConstraintParser.parse(constraint, Integer::parseInt, 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) {
List<String> countsMatches = getCountsMatches(compilation, constraint);
Comparison<Integer> comparison = constraint.comparison;
if (!comparison.compare(countsMatches.size())) {
result.addFailure(createRegexFailure(countsMatches, constraint));
}
}
private List<String> getCountsMatches(String compilation, Constraint constraint) {
Pattern pattern = Pattern.compile(constraint.nodeRegex);
Matcher matcher = pattern.matcher(compilation);
return matcher.results().map(MatchResult::group).collect(Collectors.toList());
}
private CountsRegexFailure createRegexFailure(List<String> countsMatches, Constraint constraint) {
return new CountsRegexFailure(constraint.nodeRegex, constraint.nodeId, countsMatches.size(), constraint.comparison,
countsMatches);
}
static class Constraint {
final String nodeRegex;
final Comparison<Integer> comparison;
private final int nodeId;
Constraint(String nodeRegex, Comparison<Integer> comparison, int nodeId) {
this.nodeRegex = nodeRegex;
this.comparison = comparison;
this.nodeId = nodeId;
}
}
}

View file

@ -1,74 +0,0 @@
/*
* 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, int foundValue, Comparison<Integer> 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";
}
}

View file

@ -1,73 +0,0 @@
/*
* 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));
}
}
}

View file

@ -25,125 +25,33 @@ 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 compiler.lib.ir_framework.driver.irmatching.Compilation;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.MatchableMatcher;
import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseIRRule;
import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseIRRuleBuilder;
import java.lang.reflect.Method;
import java.util.function.Consumer;
public class IRRule {
private final IRMethod irMethod;
/**
* This class represents a generic {@link IR @IR} rule of an IR method. It contains a list of compile phase specific
* IR rule versions where {@link IRNode} placeholder strings of are replaced by regexes associated with the compile phase.
*
* @see CompilePhaseIRRule
* @see IRRuleMatchResult
*/
public class IRRule implements Matchable {
private final int ruleId;
private final IR irAnno;
private final FailOn failOn;
private final Counts counts;
private final MatchableMatcher matcher;
public IRRule(IRMethod irMethod, int ruleId, IR irAnno) {
this.irMethod = irMethod;
public IRRule(int ruleId, IR irAnno, Compilation compilation) {
this.ruleId = ruleId;
this.irAnno = irAnno;
this.failOn = initFailOn(irAnno);
this.counts = initCounts(irAnno);
this.matcher = new MatchableMatcher(new CompilePhaseIRRuleBuilder(irAnno, compilation).build());
}
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;
@Override
public MatchResult match() {
return new IRRuleMatchResult(ruleId, irAnno, matcher.match());
}
}

View file

@ -23,80 +23,42 @@
package compiler.lib.ir_framework.driver.irmatching.irrule;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.OutputMatch;
import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseIRRuleMatchResult;
import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
import java.util.List;
/**
* This class represents an IR matching result of an IR rule.
* This class represents a match result of an {@link IRRule} (applied to all compile phases specified in
* {@link IR#phase()}). The {@link CompilePhaseIRRuleMatchResult} are kept in the definition order of the compile phases
* in {@link CompilePhase}.
*
* @see CheckAttributeMatchResult
* @see IRRule
*/
public class IRRuleMatchResult implements MatchResult {
private final IRRule irRule;
private CheckAttributeMatchResult failOnFailures = null;
private CheckAttributeMatchResult countsFailures = null;
private OutputMatch outputMatch;
private final AcceptChildren acceptChildren;
private final boolean failed;
private final int irRuleId;
private final IR irAnno;
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;
public IRRuleMatchResult(int irRuleId, IR irAnno, List<MatchResult> matchResults) {
this.acceptChildren = new AcceptChildren(matchResults);
this.failed = !matchResults.isEmpty();
this.irRuleId = irRuleId;
this.irAnno = irAnno;
}
@Override
public boolean fail() {
return failOnFailures != null || countsFailures != null;
return failed;
}
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();
public void accept(MatchResultVisitor visitor) {
visitor.visitIRRule(acceptChildren, irRuleId, irAnno);
}
}

View file

@ -1,90 +0,0 @@
/*
* 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 " ";
}
}

View file

@ -21,34 +21,35 @@
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.irmethod;
package compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute;
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.MatchableMatcher;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint;
import java.util.List;
/**
* Class to build the failure message output for an IR method with a missing compilation output.
* This class represents a fully parsed check attribute of an IR rule for a compile phase that is ready to be IR matched
* on. This class is part of {@link FailOn} and/or {@link Counts}.
*
* @see IRMethodMatchResult
* @see FailOn
* @see Counts
* @see Constraint
* @see CheckAttributeMatchResult
*/
class MissingCompilationMessageBuilder extends FailureMessageBuilder {
class CheckAttribute implements Matchable {
private final MatchableMatcher matcher;
private final CheckAttributeType checkAttributeType;
public MissingCompilationMessageBuilder(IRMethod irMethod) {
super(irMethod);
public CheckAttribute(CheckAttributeType checkAttributeType, List<Constraint> constraints) {
this.matcher = new MatchableMatcher(constraints);
this.checkAttributeType = checkAttributeType;
}
@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();
public MatchResult match() {
return new CheckAttributeMatchResult(checkAttributeType, matcher.match());
}
}

View file

@ -0,0 +1,60 @@
/*
* 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.checkattribute;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
import java.util.List;
/**
* This class represents a match result of a {@link CheckAttribute} (i.e. either from {@link IR#failOn} or
* {@link IR#counts}). The type of check attribute is defined by {@link CheckAttributeType}.
*
* @see CheckAttribute
* @see CheckAttributeType
*/
public class CheckAttributeMatchResult implements MatchResult {
private final AcceptChildren acceptChildren;
private final boolean failed;
private final CheckAttributeType checkAttributeType;
CheckAttributeMatchResult(CheckAttributeType checkAttributeType, List<MatchResult> matchResults) {
this.acceptChildren = new AcceptChildren(matchResults);
this.failed = !matchResults.isEmpty();
this.checkAttributeType = checkAttributeType;
}
@Override
public boolean fail() {
return failed;
}
@Override
public void accept(MatchResultVisitor visitor) {
visitor.visitCheckAttribute(acceptChildren, checkAttributeType);
}
}

View file

@ -0,0 +1,34 @@
/*
* 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.checkattribute;
/**
* This enum denotes the check attribute type of a check attribute.
*
* @see CheckAttribute
* @see CheckAttributeMatchResult
*/
public enum CheckAttributeType {
FAIL_ON, COUNTS
}

View file

@ -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.irrule.checkattribute;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint;
import java.util.List;
/**
* This class represents a fully parsed {@link IR#counts()} attribute of an IR rule for a compile phase that is ready
* to be IR matched on.
*
* @see IR#counts()
*/
public class Counts implements Matchable {
private final CheckAttribute checkAttribute;
public Counts(List<Constraint> constraints) {
this.checkAttribute = new CheckAttribute(CheckAttributeType.COUNTS, constraints);
}
@Override
public MatchResult match() {
return checkAttribute.match();
}
}

View file

@ -0,0 +1,74 @@
/*
* 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.checkattribute;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.SuccessResult;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* This class represents a fully parsed {@link IR#failOn()} attribute of an IR rule for a compile phase that is ready
* to be IR matched on. This class provides a quick check regex by simply looking for any occurrence of any constraint
* regex. Only if that fails, we need to check each constraint individually to report which one failed.
*
* @see IR#failOn()
*/
public class FailOn implements Matchable {
private final Matchable checkAttribute;
private final List<Constraint> constraints;
private final String compilationOutput;
public FailOn(List<Constraint> constraints, String compilationOutput) {
this.checkAttribute = new CheckAttribute(CheckAttributeType.FAIL_ON, constraints);
this.constraints = constraints;
this.compilationOutput = compilationOutput;
}
@Override
public MatchResult match() {
if (hasNoMatchQuick()) {
return SuccessResult.getInstance();
}
return checkAttribute.match();
}
/**
* Quick check: Look for any occurrence of any regex by creating the following pattern to match against:
* "regex_1|regex_2|...|regex_n"
*/
private boolean hasNoMatchQuick() {
String patternString = constraints.stream().map(Constraint::nodeRegex).collect(Collectors.joining("|"));
Pattern pattern = Pattern.compile(String.join("|", patternString));
Matcher matcher = pattern.matcher(compilationOutput);
return !matcher.find();
}
}

View file

@ -0,0 +1,75 @@
/*
* 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.checkattribute.parsing;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.IRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.action.ConstraintAction;
import compiler.lib.ir_framework.shared.TestFormat;
import java.util.*;
/**
* This class reads the check attribute strings as found in ({@link IR#failOn()} or {@link IR#counts()}) and groups them
* into constraints. For each constraint, a {@link ConstraintAction} is performed which creates an object. These objects
* are then returned to the caller.
*
* @see IR#failOn()
* @see IR#counts()
* @see ConstraintAction
*/
public class CheckAttributeReader<R> {
private final ListIterator<String> iterator;
private final ConstraintAction<R> constraintAction;
public CheckAttributeReader(String[] checkAttributeStrings, ConstraintAction<R> constraintAction) {
this.iterator = Arrays.stream(checkAttributeStrings).toList().listIterator();
this.constraintAction = constraintAction;
}
public void read(Collection<R> result) {
int index = 1;
while (iterator.hasNext()) {
String node = iterator.next();
CheckAttributeString userPostfix = readUserPostfix(node);
RawIRNode rawIRNode = new RawIRNode(node, userPostfix);
result.add(constraintAction.apply(iterator, rawIRNode, index++));
}
}
public final CheckAttributeString readUserPostfix(String node) {
if (IRNode.isCompositeIRNode(node)) {
String irNode = IRNode.getIRNodeAccessString(node);
int nextIndex = iterator.nextIndex();
TestFormat.checkNoReport(iterator.hasNext(), "Must provide additional value at index " +
nextIndex + " right after " + irNode);
CheckAttributeString userPostfix = new CheckAttributeString(iterator.next());
TestFormat.checkNoReport(userPostfix.isValidUserPostfix(), "Provided empty string for composite node " +
irNode + " at index " + nextIndex);
return userPostfix;
} else {
return CheckAttributeString.invalid();
}
}
}

View file

@ -0,0 +1,47 @@
/*
* 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.checkattribute.parsing;
import compiler.lib.ir_framework.IR;
/**
* This class represents a single string found in a check attribute of an {@link IR} annotation.
*
* @see IR
*/
record CheckAttributeString(String value) {
private static final CheckAttributeString INVALID = new CheckAttributeString("");
public boolean isValid() {
return this != INVALID;
}
public boolean isValidUserPostfix() {
return !value.isEmpty();
}
public static CheckAttributeString invalid() {
return INVALID;
}
}

View file

@ -0,0 +1,79 @@
/*
* 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.checkattribute.parsing;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.IRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.action.ConstraintAction;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.action.CreateRawConstraintAction;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.action.DefaultPhaseConstraintAction;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* This class parses the check attribute strings of ({@link IR#failOn()} or {@link IR#counts()}) as found in a
* {@link IR @IR} annotation without replacing placeholder IR strings, yet. For each constraint (i.e. all consecutive
* strings in the check attribute that eventually form a constraint) we apply a {@link ConstraintAction} which defines
* the action that is performed for the constraint.
*
* @see IR#failOn()
* @see IR#counts()
* @see ConstraintAction
*/
public class CheckAttributeStrings {
private final String[] checkAttributeStrings;
public CheckAttributeStrings(String[] checkAttributeStrings) {
this.checkAttributeStrings = checkAttributeStrings;
}
/**
* Walk over the check attribute strings as found in the {@link IR} annotation and create {@link RawConstraint}
* objects for them. Return them in a list.
*/
public final List<RawConstraint> createRawConstraints(CreateRawConstraintAction createRawConstraintAction) {
CheckAttributeReader<RawConstraint> reader = new CheckAttributeReader<>(checkAttributeStrings,
createRawConstraintAction);
List<RawConstraint> rawConstraints = new ArrayList<>();
reader.read(rawConstraints);
return rawConstraints;
}
/**
* Walk over the check attribute strings as found in the {@link IR annotation} and return the default phase for
* {@link IRNode} constraints.
*/
public final Set<CompilePhase> parseDefaultCompilePhases(DefaultPhaseConstraintAction defaultPhaseConstraintAction) {
Set<CompilePhase> compilePhases = new HashSet<>();
CheckAttributeReader<CompilePhase> reader = new CheckAttributeReader<>(checkAttributeStrings,
defaultPhaseConstraintAction);
reader.read(compilePhases);
return compilePhases;
}
}

View file

@ -21,28 +21,20 @@
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.irrule;
package compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.Set;
/**
* Base class representing a check attribute of an IR rule.
*
* @see IR
* Interface offering different parsing operations on the raw strings as found in {@link IR} check attributes.
*/
abstract class CheckAttribute {
public interface RawCheckAttribute {
List<RawConstraint> createRawConstraints();
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;
}
Set<CompilePhase> parseDefaultCompilePhases();
}

View file

@ -0,0 +1,56 @@
/*
* 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.checkattribute.parsing;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.action.CreateRawCountsConstraintAction;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.action.DefaultPhaseCountsConstraintAction;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint;
import java.util.List;
import java.util.Set;
/**
* This class offers different parsing operations on the raw strings as found in a {@link IR#counts()} check attribute.
*
* @see IR#counts
*/
public class RawCounts implements RawCheckAttribute {
private final CheckAttributeStrings checkAttributeStrings;
public RawCounts(String[] checkAttributeStrings) {
this.checkAttributeStrings = new CheckAttributeStrings(checkAttributeStrings);
}
@Override
public List<RawConstraint> createRawConstraints() {
return checkAttributeStrings.createRawConstraints(new CreateRawCountsConstraintAction());
}
@Override
public Set<CompilePhase> parseDefaultCompilePhases() {
return checkAttributeStrings.parseDefaultCompilePhases(new DefaultPhaseCountsConstraintAction());
}
}

View file

@ -0,0 +1,56 @@
/*
* 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.checkattribute.parsing;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.action.CreateRawFailOnConstraintAction;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.action.DefaultPhaseFailOnConstraintAction;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint;
import java.util.List;
import java.util.Set;
/**
* This class offers different parsing operations on the raw strings as found in a {@link IR#failOn()} check attribute.
*
* @see IR#failOn()
*/
public class RawFailOn implements RawCheckAttribute {
private final CheckAttributeStrings checkAttributeStrings;
public RawFailOn(String[] checkAttributeStrings) {
this.checkAttributeStrings = new CheckAttributeStrings(checkAttributeStrings);
}
@Override
public List<RawConstraint> createRawConstraints() {
return checkAttributeStrings.createRawConstraints(new CreateRawFailOnConstraintAction());
}
@Override
public Set<CompilePhase> parseDefaultCompilePhases() {
return checkAttributeStrings.parseDefaultCompilePhases(new DefaultPhaseFailOnConstraintAction());
}
}

View file

@ -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.irrule.checkattribute.parsing;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IRNode;
/**
* This class represents a "raw IR node" as read from a check attribute. It has a node part that either represents an
* {@link IRNode} placeholder string or a user defined regex. In the former case, we could additionally have a user
* postfix string. This raw IR node is not specific to any compile phase (i.e. the IR node placeholder is not replaced
* by an actual regex, yet, and thus is named "raw").
*
* @see IRNode
*/
public class RawIRNode {
private final String node;
private final CheckAttributeString userPostfix;
public RawIRNode(String node, CheckAttributeString userPostfix) {
this.node = node;
this.userPostfix = userPostfix;
}
public String irNodePlaceholder() {
return IRNode.getIRNodeAccessString(node);
}
public CompilePhase defaultCompilePhase() {
return IRNode.getDefaultPhase(node);
}
public String regex(CompilePhase compilePhase) {
String nodeRegex = node;
if (IRNode.isIRNode(node)) {
nodeRegex = IRNode.getRegexForCompilePhase(node, compilePhase);
if (userPostfix.isValid()) {
nodeRegex = nodeRegex.replaceAll(IRNode.IS_REPLACED, userPostfix.value());
}
}
return nodeRegex;
}
}

View file

@ -0,0 +1,38 @@
/*
* 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.checkattribute.parsing.action;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode;
import java.util.ListIterator;
/**
* Interface describing an action that can performed when reading a constraint of an {@link IR} check attribute. The
* action creates a new object and returns it.
*/
public interface ConstraintAction<R> {
R apply(ListIterator<String> iterator, RawIRNode rawIRNode, int constraintId);
}

View file

@ -0,0 +1,65 @@
/*
* 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.checkattribute.parsing.action;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode;
import compiler.lib.ir_framework.shared.Comparison;
import compiler.lib.ir_framework.shared.ComparisonConstraintParser;
import compiler.lib.ir_framework.shared.TestFormat;
import compiler.lib.ir_framework.shared.TestFormatException;
import java.util.ListIterator;
/**
* This class represents a count string of a {@link IR} check attribute.
*/
class CountString {
private final ListIterator<String> iterator;
private final RawIRNode rawIRNode;
public CountString(ListIterator<String> iterator, RawIRNode rawIRNode) {
this.iterator = iterator;
this.rawIRNode = rawIRNode;
}
public Comparison<Integer> parse() {
TestFormat.checkNoReport(iterator.hasNext(), "Missing count for node " + rawIRNode.irNodePlaceholder());
String countsString = iterator.next();
try {
return ComparisonConstraintParser.parse(countsString, CountString::parsePositiveInt);
} catch (TestFormatException e) {
String irNodeString = rawIRNode.irNodePlaceholder();
throw new TestFormatException(e.getMessage() + ", node " + irNodeString + ", in count string \"" + countsString + "\"");
}
}
public static int parsePositiveInt(String s) {
int result = Integer.parseInt(s);
if (result < 0) {
throw new NumberFormatException("cannot be negative");
}
return result;
}
}

View file

@ -0,0 +1,37 @@
/*
* 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.checkattribute.parsing.action;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint;
import java.util.ListIterator;
/**
* Interface describing an action which creates a {@link RawConstraint}.
*/
public interface CreateRawConstraintAction extends ConstraintAction<RawConstraint> {
@Override
RawConstraint apply(ListIterator<String> iterator, RawIRNode rawIRNode, int constraintId);
}

View file

@ -0,0 +1,42 @@
/*
* 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.checkattribute.parsing.action;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawCountsConstraint;
import compiler.lib.ir_framework.shared.Comparison;
import java.util.ListIterator;
/**
* This action class creates a {@link RawCountsConstraint}.
*/
public class CreateRawCountsConstraintAction implements CreateRawConstraintAction {
@Override
public RawConstraint apply(ListIterator<String> iterator, RawIRNode rawIRNode, int constraintIndex) {
Comparison<Integer> comparison = new CountString(iterator, rawIRNode).parse();
return new RawCountsConstraint(rawIRNode, comparison, constraintIndex);
}
}

View file

@ -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.irrule.checkattribute.parsing.action;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawFailOnConstraint;
import java.util.ListIterator;
/**
* This action class creates a {@link RawConstraint}.
*/
public class CreateRawFailOnConstraintAction implements CreateRawConstraintAction {
@Override
public RawConstraint apply(ListIterator<String> iterator, RawIRNode rawIRNode, int constraintIndex) {
return new RawFailOnConstraint(rawIRNode, constraintIndex);
}
}

View file

@ -0,0 +1,38 @@
/*
* 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.checkattribute.parsing.action;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode;
import java.util.ListIterator;
/**
* Interface describing an action which fetches the default {@link CompilePhase} of an {@link IRNode}.
*/
public interface DefaultPhaseConstraintAction extends ConstraintAction<CompilePhase> {
@Override
CompilePhase apply(ListIterator<String> iterator, RawIRNode rawIRNode, int constraintId);
}

View file

@ -0,0 +1,42 @@
/*
* 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.checkattribute.parsing.action;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.IRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode;
import java.util.ListIterator;
/**
* This class fetches the default {@link CompilePhase} of an {@link IRNode} of a {@link IR#failOn} check attribute.
*/
public class DefaultPhaseCountsConstraintAction implements DefaultPhaseConstraintAction {
@Override
public CompilePhase apply(ListIterator<String> iterator, RawIRNode rawIRNode, int constraintId) {
new CountString(iterator, rawIRNode).parse();
return rawIRNode.defaultCompilePhase();
}
}

View file

@ -21,29 +21,21 @@
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.irrule;
package compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.action;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.IRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode;
import java.util.ArrayList;
import java.util.ListIterator;
/**
* Class representing a result of an applied counts attribute of an IR rule.
*
* @see IR#counts()
* This class fetches the default {@link CompilePhase} of an {@link IRNode} of a {@link IR#counts} check attribute.
*/
class CountsMatchResult extends CheckAttributeMatchResult {
public void addFailure(RegexFailure regexFailure) {
if (regexFailures == null) {
regexFailures = new ArrayList<>();
}
regexFailures.add(regexFailure);
}
public class DefaultPhaseFailOnConstraintAction implements DefaultPhaseConstraintAction {
@Override
public String buildFailureMessage() {
return " - counts: Graph contains wrong number of nodes:" + System.lineSeparator()
+ collectRegexFailureMessages();
public CompilePhase apply(ListIterator<String> iterator, RawIRNode rawIRNode, int constraintId) {
return rawIRNode.defaultCompilePhase();
}
}

View file

@ -0,0 +1,79 @@
/*
* 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.constraint;
import compiler.lib.ir_framework.IRNode;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.FailOn;
import compiler.lib.ir_framework.shared.Comparison;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* This class represents a single constraint of a check attribute of an IR rule for a compile phase. It stores a
* ready to be used regex for a compile phase (i.e. all {@link IRNode} placeholder strings are updated and composite nodes
* merged) which can be used for matching. A {@link ConstraintCheck} decides if the matching on the constraint fails.
*
* @see FailOn
*/
public class Constraint implements Matchable {
private final ConstraintCheck constraintCheck;
private final String nodeRegex;
private final String compilationOutput;
private Constraint(ConstraintCheck constraintCheck, String nodeRegex, String compilationOutput) {
this.constraintCheck = constraintCheck;
this.nodeRegex = nodeRegex;
this.compilationOutput = compilationOutput;
}
public static Constraint createFailOn(String nodeRegex, int constraintId, String compilationOutput) {
return new Constraint(new FailOnConstraintCheck(nodeRegex, constraintId), nodeRegex, compilationOutput);
}
public static Constraint createCounts(String nodeRegex, int constraintId, Comparison<Integer> comparison,
String compilationOutput) {
return new Constraint(new CountsConstraintCheck(nodeRegex, constraintId, comparison), nodeRegex, compilationOutput);
}
public String nodeRegex() {
return nodeRegex;
}
@Override
public MatchResult match() {
List<String> matchedNodes = matchNodes(compilationOutput);
return constraintCheck.check(matchedNodes);
}
private List<String> matchNodes(String compilationOutput) {
Pattern pattern = Pattern.compile(nodeRegex);
Matcher matcher = pattern.matcher(compilationOutput);
return matcher.results().map(java.util.regex.MatchResult::group).collect(Collectors.toList());
}
}

View file

@ -21,23 +21,15 @@
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.irmethod;
package compiler.lib.ir_framework.driver.irmatching.irrule.constraint;
import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import java.util.List;
/**
* Base class to build the failure message output for an IR method.
*
* @see IRMethodMatchResult
* Interface to represent a check on a single {@link Constraint}.
*/
abstract class FailureMessageBuilder {
protected final IRMethod irMethod;
public FailureMessageBuilder(IRMethod irMethod) {
this.irMethod = irMethod;
}
abstract public String build();
interface ConstraintCheck {
MatchResult check(List<String> matchedNodes);
}

View file

@ -21,29 +21,23 @@
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.irrule;
package compiler.lib.ir_framework.driver.irmatching.irrule.constraint;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import java.util.List;
/**
* This class represents an IR matching failure of a regex of a failOn attribute of an IR rule.
* Interface representing a match result of a {@link Constraint} on a compile phase output which failed.
*
* @see FailOn
* @see Constraint
*/
class FailOnRegexFailure extends RegexFailure {
public FailOnRegexFailure(String nodeRegex, int nodeId, List<String> matches) {
super(nodeRegex, nodeId, matches);
}
public interface ConstraintFailure extends MatchResult {
@Override
public String buildFailureMessage() {
return getRegexLine()
+ getMatchedNodesBlock();
}
@Override
protected String getMatchedPrefix() {
return "Matched forbidden";
default boolean fail() {
return true;
}
String nodeRegex();
int constraintId();
List<String> matchedNodes();
}

View file

@ -0,0 +1,55 @@
/*
* 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.constraint;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.shared.Comparison;
import java.util.List;
/**
* This class provides a check on a single {@link IR#counts()} {@link Constraint}.
*
* @see Constraint
*/
class CountsConstraintCheck implements ConstraintCheck {
private final String nodeRegex;
private final int constraintId; // constraint indices start at 1.
private final Comparison<Integer> comparison;
public CountsConstraintCheck(String nodeRegex, int constraintId, Comparison<Integer> comparison) {
this.comparison = comparison;
this.nodeRegex = nodeRegex;
this.constraintId = constraintId;
}
@Override
public MatchResult check(List<String> matchedNodes) {
if (!comparison.compare(matchedNodes.size())) {
return new CountsConstraintFailure(nodeRegex, constraintId, matchedNodes, comparison);
}
return SuccessResult.getInstance();
}
}

View file

@ -0,0 +1,44 @@
/*
* 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.constraint;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.Counts;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
import compiler.lib.ir_framework.shared.Comparison;
import java.util.List;
/**
* This class represents a failed match result of a counts {@link Constraint} on a compile phase output.
*
* @see Constraint
* @see Counts
*/
public record CountsConstraintFailure(String nodeRegex, int constraintId, List<String> matchedNodes,
Comparison<Integer> comparison) implements ConstraintFailure {
@Override
public void accept(MatchResultVisitor visitor) {
visitor.visitCountsConstraint(this);
}
}

View file

@ -21,7 +21,7 @@
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.irrule;
package compiler.lib.ir_framework.driver.irmatching.irrule.constraint;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
@ -29,31 +29,24 @@ 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.
* This class provides a check on a single {@link IR#failOn()} {@link Constraint}.
*
* @see IR
* @see Constraint
*/
abstract class CheckAttributeMatchResult implements MatchResult {
protected List<RegexFailure> regexFailures = null;
class FailOnConstraintCheck implements ConstraintCheck {
private final String nodeRegex;
private final int constraintId; // constraint indices start at 1.
public FailOnConstraintCheck(String nodeRegex, int constraintId) {
this.nodeRegex = nodeRegex;
this.constraintId = constraintId;
}
@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;
public MatchResult check(List<String> matchedNodes) {
if (!matchedNodes.isEmpty()) {
return new FailOnConstraintFailure(nodeRegex, constraintId, matchedNodes);
}
}
protected String collectRegexFailureMessages() {
StringBuilder failMsg = new StringBuilder();
for (RegexFailure regexFailure : regexFailures) {
failMsg.append(regexFailure.buildFailureMessage());
}
return failMsg.toString();
return SuccessResult.getInstance();
}
}

View file

@ -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.constraint;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.Counts;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
import java.util.List;
/**
* This class represents a failed match result of a failOn {@link Constraint} on a compile phase output.
*
* @see Constraint
* @see Counts
*/
public record FailOnConstraintFailure(String nodeRegex, int constraintId, List<String> matchedNodes)
implements ConstraintFailure {
public FailOnConstraintFailure {
TestFramework.check(!matchedNodes.isEmpty(), "must have at least one matched node");
}
@Override
public void accept(MatchResultVisitor visitor) {
visitor.visitFailOnConstraint(this);
}
}

View file

@ -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.irrule.constraint;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
/**
* This class represents a successful match result of any {@link Matchable} object.
*/
public class SuccessResult implements MatchResult {
private static final SuccessResult INSTANCE = new SuccessResult();
private SuccessResult() {}
public static SuccessResult getInstance() {
return INSTANCE;
}
@Override
public boolean fail() {
return false;
}
@Override
public void accept(MatchResultVisitor visitor) {
// Must not be visited.
}
}

View file

@ -0,0 +1,42 @@
/*
* 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.constraint.raw;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.IRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint;
/**
* Interface to represent a single raw constraint as found in the {@link IR @IR} annotation (i.e. {@link IRNode}
* placeholder strings are not replaced by regexes, yet). A raw constraint can be parsed into a {@link Constraint} by
* calling {@link #parse(CompilePhase, String)}. This replaces the IR node placeholder strings by actual regexes and
* merges composite nodes together.
*
* @see Constraint
*/
public interface RawConstraint {
CompilePhase defaultCompilePhase();
Constraint parse(CompilePhase compilePhase, String compilationOutput);
}

View file

@ -0,0 +1,60 @@
/*
* 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.constraint.raw;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint;
import compiler.lib.ir_framework.shared.Comparison;
/**
* This class represents a raw constraint of a {@link IR#counts()} attribute.
*
* @see IR#counts()
*/
public class RawCountsConstraint implements RawConstraint {
private final RawIRNode rawIRNode;
private final int constraintIndex;
private final Comparison<Integer> comparison;
public RawCountsConstraint(RawIRNode rawIRNode, Comparison<Integer> comparison, int constraintIndex) {
this.rawIRNode = rawIRNode;
this.constraintIndex = constraintIndex;
this.comparison = comparison;
}
@Override
public CompilePhase defaultCompilePhase() {
return rawIRNode.defaultCompilePhase();
}
@Override
public Constraint parse(CompilePhase compilePhase, String compilationOutput) {
TestFramework.check(compilePhase != CompilePhase.DEFAULT, "must not be default");
return Constraint.createCounts(rawIRNode.regex(compilePhase), constraintIndex, comparison, compilationOutput);
}
}

View file

@ -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.driver.irmatching.irrule.constraint.raw;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint;
/**
* This class represents a raw constraint of a {@link IR#failOn()} attribute.
*
* @see IR#failOn()
*/
public class RawFailOnConstraint implements RawConstraint {
private final RawIRNode rawIRNode;
private final int constraintIndex;
public RawFailOnConstraint(RawIRNode rawIRNode, int constraintIndex) {
this.rawIRNode = rawIRNode;
this.constraintIndex = constraintIndex;
}
@Override
public CompilePhase defaultCompilePhase() {
return rawIRNode.defaultCompilePhase();
}
@Override
public Constraint parse(CompilePhase compilePhase, String compilationOutput) {
TestFramework.check(compilePhase != CompilePhase.DEFAULT, "must not be default");
return Constraint.createFailOn(rawIRNode.regex(compilePhase), constraintIndex, compilationOutput);
}
}

View file

@ -0,0 +1,65 @@
/*
* 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.phase;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IRNode;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.MatchableMatcher;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.Counts;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.FailOn;
import java.util.List;
/**
* This class represents an IR rule of an IR method for a specific compile phase. It contains fully parsed (i.e.
* all placeholder strings of {@link IRNode} replaced and composite nodes merged) {@link FailOn} and/or {@link Counts}
* check attributes which are ready to be matched on.
*
* @see FailOn
* @see Counts
* @see CompilePhaseIRRuleMatchResult
*/
public class CompilePhaseIRRule implements CompilePhaseIRRuleMatchable {
private final CompilePhase compilePhase;
private final MatchableMatcher matcher;
private final String compilationOutput;
public CompilePhaseIRRule(CompilePhase compilePhase, List<Matchable> checkAttributes, String compilationOutput) {
this.compilePhase = compilePhase;
this.matcher = new MatchableMatcher(checkAttributes);
this.compilationOutput = compilationOutput;
}
@Override
public MatchResult match() {
return new CompilePhaseIRRuleMatchResult(compilePhase, compilationOutput, matcher.match());
}
@Override
public CompilePhase compilePhase() {
return compilePhase;
}
}

View file

@ -0,0 +1,123 @@
/*
* 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.phase;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.IRNode;
import compiler.lib.ir_framework.driver.irmatching.Compilation;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.Counts;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.FailOn;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawCounts;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawFailOn;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint;
import compiler.lib.ir_framework.shared.TestFormat;
import java.util.*;
/**
* This class creates a list of {@link CompilePhaseIRRule} for each specified compile phase in {@link IR#phase()} of an
* IR rule. Default compile phases of {@link IRNode} placeholder strings as found in {@link RawConstraint} objects are
* replaced by the actual default phases. The resulting parsed {@link Constraint} objects which now belong to a
* non-default compile phase are moved to the check attribute matchables which represent these compile phases.
*
* @see CompilePhaseIRRule
*/
public class CompilePhaseIRRuleBuilder {
private final IR irAnno;
private final List<RawConstraint> rawFailOnConstraints;
private final List<RawConstraint> rawCountsConstraints;
private final Compilation compilation;
private final SortedSet<CompilePhaseIRRuleMatchable> compilePhaseIRRules = new TreeSet<>();
public CompilePhaseIRRuleBuilder(IR irAnno, Compilation compilation) {
this.irAnno = irAnno;
this.compilation = compilation;
this.rawFailOnConstraints = new RawFailOn(irAnno.failOn()).createRawConstraints();
this.rawCountsConstraints = new RawCounts(irAnno.counts()).createRawConstraints();
}
public SortedSet<CompilePhaseIRRuleMatchable> build() {
CompilePhase[] compilePhases = irAnno.phase();
TestFormat.checkNoReport(new HashSet<>(List.of(compilePhases)).size() == compilePhases.length,
"Cannot specify a compile phase twice");
for (CompilePhase compilePhase : compilePhases) {
if (compilePhase == CompilePhase.DEFAULT) {
createCompilePhaseIRRulesForDefault();
} else {
createCompilePhaseIRRule(compilePhase);
}
}
return compilePhaseIRRules;
}
private void createCompilePhaseIRRulesForDefault() {
DefaultPhaseRawConstraintParser parser = new DefaultPhaseRawConstraintParser(compilation);
Map<CompilePhase, List<Matchable>> checkAttributesForCompilePhase =
parser.parse(rawFailOnConstraints, rawCountsConstraints);
checkAttributesForCompilePhase.forEach((compilePhase, constraints) -> {
if (compilation.hasOutput(compilePhase)) {
compilePhaseIRRules.add(new CompilePhaseIRRule(compilePhase, constraints,
compilation.output(compilePhase)));
} else {
compilePhaseIRRules.add(new CompilePhaseNoCompilationIRRule(compilePhase));
}
});
}
private void createCompilePhaseIRRule(CompilePhase compilePhase) {
List<Constraint> failOnConstraints = parseRawConstraints(rawFailOnConstraints, compilePhase);
List<Constraint> countsConstraints = parseRawConstraints(rawCountsConstraints, compilePhase);
if (compilation.hasOutput(compilePhase)) {
createValidCompilePhaseIRRule(compilePhase, failOnConstraints, countsConstraints);
} else {
compilePhaseIRRules.add(new CompilePhaseNoCompilationIRRule(compilePhase));
}
}
private void createValidCompilePhaseIRRule(CompilePhase compilePhase, List<Constraint> failOnConstraints,
List<Constraint> countsConstraints) {
String compilationOutput = compilation.output(compilePhase);
List<Matchable> checkAttributes = new ArrayList<>();
if (!failOnConstraints.isEmpty()) {
checkAttributes.add(new FailOn(failOnConstraints, compilationOutput));
}
if (!countsConstraints.isEmpty()) {
checkAttributes.add(new Counts(countsConstraints));
}
compilePhaseIRRules.add(new CompilePhaseIRRule(compilePhase, checkAttributes, compilation.output(compilePhase)));
}
private List<Constraint> parseRawConstraints(List<RawConstraint> rawConstraints,
CompilePhase compilePhase) {
List<Constraint> constraintResultList = new ArrayList<>();
for (RawConstraint rawConstraint : rawConstraints) {
constraintResultList.add(rawConstraint.parse(compilePhase, compilation.output(compilePhase)));
}
return constraintResultList;
}
}

View file

@ -0,0 +1,61 @@
/*
* 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.phase;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
import java.util.List;
/**
* This class represents a match result of a {@link CompilePhaseIRRule} (i.e. an IR rule applied on a compile phase).
*
* @see CompilePhaseIRRule
*/
public class CompilePhaseIRRuleMatchResult implements MatchResult {
private final AcceptChildren acceptChildren;
private final boolean failed;
private final CompilePhase compilePhase;
private final String compilationOutput;
public CompilePhaseIRRuleMatchResult(CompilePhase compilePhase, String compilationOutput,
List<MatchResult> matchResults) {
this.acceptChildren = new AcceptChildren(matchResults);
this.failed = !matchResults.isEmpty();
this.compilePhase = compilePhase;
this.compilationOutput = compilationOutput;
}
@Override
public boolean fail() {
return failed;
}
@Override
public void accept(MatchResultVisitor visitor) {
visitor.visitCompilePhaseIRRule(acceptChildren, compilePhase, compilationOutput);
}
}

View file

@ -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.phase;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
/**
* Interface for all matchable objects related to compile phase IR rules.
*
* @see CompilePhaseIRRule
* @see CompilePhaseNoCompilationIRRule
*/
public interface CompilePhaseIRRuleMatchable extends Matchable, Comparable<CompilePhaseIRRuleMatchable> {
CompilePhase compilePhase();
/**
* Sort by compile phase enum definition order.
*/
@Override
default int compareTo(CompilePhaseIRRuleMatchable other) {
return this.compilePhase().compareTo(other.compilePhase());
}
}

View file

@ -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.irrule.phase;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
/**
* This class represents a special compile phase IR rule where no compilation output was found for the associated
* compile phase. This could happen, if the user-defined test code does not exercise the code path that emits this
* compile phase.
*
* @see CompilePhaseNoCompilationIRRuleMatchResult
*/
public record CompilePhaseNoCompilationIRRule(CompilePhase compilePhase) implements CompilePhaseIRRuleMatchable {
@Override
public MatchResult match() {
return new CompilePhaseNoCompilationIRRuleMatchResult(compilePhase);
}
}

View file

@ -0,0 +1,47 @@
/*
* 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.phase;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.driver.irmatching.MatchResult;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
/**
* This class represents a special match result of {@link CompilePhaseNoCompilationIRRule} where the compilation output
* for the compile phase was empty.
*
* @see CompilePhaseNoCompilationIRRule
*/
public record CompilePhaseNoCompilationIRRuleMatchResult(CompilePhase compilePhase) implements MatchResult {
@Override
public boolean fail() {
return true;
}
@Override
public void accept(MatchResultVisitor visitor) {
visitor.visitNoCompilePhaseCompilation(compilePhase);
}
}

View file

@ -0,0 +1,115 @@
/*
* 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.phase;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.driver.irmatching.Compilation;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.CheckAttributeType;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.Counts;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.FailOn;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint;
import compiler.lib.ir_framework.shared.TestFrameworkException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* This class creates {@link FailOn} and {@link Counts} objects for the default compile phase by parsing the raw
* constraints. Each {@link RawConstraint} has a well-defined default phase. This class collects all parsed
* {@link Constraint} objects for a compile phase in order to create {@link FailOn} and {@link Counts} objects with them.
*/
class DefaultPhaseRawConstraintParser {
private final Compilation compilation;
public DefaultPhaseRawConstraintParser(Compilation compilation) {
this.compilation = compilation;
}
public Map<CompilePhase, List<Matchable>> parse(List<RawConstraint> rawFailOnConstraints,
List<RawConstraint> rawCountsConstraints) {
Map<CompilePhase, Matchable> failOnForCompilePhase = parseRawConstraints(rawFailOnConstraints,
CheckAttributeType.FAIL_ON);
Map<CompilePhase, Matchable> countsForCompilePhase = parseRawConstraints(rawCountsConstraints,
CheckAttributeType.COUNTS);
return mergeCheckAttributesForCompilePhase(failOnForCompilePhase, countsForCompilePhase);
}
private Map<CompilePhase, Matchable> parseRawConstraints(List<RawConstraint> rawConstraints,
CheckAttributeType checkAttributeType) {
Map<CompilePhase, List<Constraint>> matchableForCompilePhase = new HashMap<>();
for (RawConstraint rawConstraint : rawConstraints) {
CompilePhase compilePhase = rawConstraint.defaultCompilePhase();
List<Constraint> checkAttribute =
matchableForCompilePhase.computeIfAbsent(compilePhase, k -> new ArrayList<>());
checkAttribute.add(rawConstraint.parse(compilePhase, compilation.output(compilePhase)));
}
return replaceConstraintsWithCheckAttribute(matchableForCompilePhase, checkAttributeType);
}
private Map<CompilePhase, Matchable>
replaceConstraintsWithCheckAttribute(Map<CompilePhase, List<Constraint>> matchableForCompilePhase,
CheckAttributeType checkAttributeType) {
return matchableForCompilePhase
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> createCheckAttribute(checkAttributeType,
entry.getKey(), entry.getValue())));
}
private Matchable createCheckAttribute(CheckAttributeType checkAttributeType, CompilePhase compilePhase,
List<Constraint> constraints) {
switch (checkAttributeType) {
case FAIL_ON -> {
return new FailOn(constraints, compilation.output(compilePhase));
}
case COUNTS -> {
return new Counts(constraints);
}
default -> throw new TestFrameworkException("unsupported: " + checkAttributeType);
}
}
private static Map<CompilePhase, List<Matchable>>
mergeCheckAttributesForCompilePhase(Map<CompilePhase, Matchable> failOnForCompilePhase,
Map<CompilePhase, Matchable> countsForCompilePhase) {
Map<CompilePhase, List<Matchable>> result = new HashMap<>();
addCheckAttribute(failOnForCompilePhase, result);
addCheckAttribute(countsForCompilePhase, result);
return result;
}
private static void addCheckAttribute(Map<CompilePhase, Matchable> failOnForCompilePhase,
Map<CompilePhase, List<Matchable>> result) {
failOnForCompilePhase.forEach((compilePhase, matchable) -> {
List<Matchable> list = result.computeIfAbsent(compilePhase, k -> new ArrayList<>());
list.add(matchable);
});
}
}

View file

@ -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.mapping;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.IRNode;
/**
* This interface represents an IR node mapping entry in {@code IR_NODE_MAPPINGS} in {@link IRNode}. Each entry must
* return a regex for a {@link CompilePhase} or null if it does not support the compile phase. Additionally, a default
* compile phase must be specified to fall back to when a user test specifies {@link CompilePhase#DEFAULT} in
* {@link IR#phase} or does not provide the {@link IR#phase} attribute.
*
* @see IRNode
* @see CompilePhase
*/
public interface IRNodeMapEntry {
/**
* Return the regex string which shall be used by the IR framework when matching on {@code compilePhase}.
*/
String regexForCompilePhase(CompilePhase compilePhase);
/**
* Return the default compile phase that shall be used for an {@link IRNode} placeholeder string when the user test
* specifies {@link CompilePhase#DEFAULT}.
*/
CompilePhase defaultCompilePhase();
}

View file

@ -0,0 +1,79 @@
/*
* 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.mapping;
import compiler.lib.ir_framework.CompilePhase;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* This class represents a mapping entry for an IR node that maps to different regexes depending on the compile phase.
* This is done by providing a specific {@link PhaseInterval} (i.e. a continuous compile phase range) for each regex.
* If there is only one {@link PhaseInterval}, a {@link SinglePhaseRangeEntry} should be used.
*
* @see PhaseInterval
* @see SinglePhaseRangeEntry
*/
public class MultiPhaseRangeEntry implements IRNodeMapEntry {
private final Map<PhaseInterval, String> intervalToRegex;
private final CompilePhase defaultCompilePhase;
public MultiPhaseRangeEntry(CompilePhase defaultCompilePhase, Map<PhaseInterval, String> intervalToRegex) {
checkOverlap(new ArrayList<>(intervalToRegex.keySet()));
this.intervalToRegex = intervalToRegex;
this.defaultCompilePhase = defaultCompilePhase;
}
/**
* Checks that there is no compile phase overlap of any {@link PhaseInterval} objects in {@code phaseRanges}.
*/
private static void checkOverlap(List<PhaseInterval> phaseRanges) {
// Sort ascending by start field of phase range.
phaseRanges.sort((i1, i2) -> i1.start().ordinal() - i2.end().ordinal());
for (int i = 1; i < phaseRanges.size(); i++) {
if (phaseRanges.get(i - 1).startIndex() > phaseRanges.get(i).endIndex()) {
// Previous phase range ends after start of current phase range -> overlap
throw new OverlappingPhaseRangesException(phaseRanges.get(i - 1), phaseRanges.get(i));
}
}
}
@Override
public String regexForCompilePhase(CompilePhase compilePhase) {
for (var entry : intervalToRegex.entrySet()) {
PhaseInterval interval = entry.getKey();
if (interval.includes(compilePhase)) {
return entry.getValue();
}
}
return null;
}
@Override
public CompilePhase defaultCompilePhase() {
return defaultCompilePhase;
}
}

View file

@ -21,16 +21,17 @@
* questions.
*/
package compiler.lib.ir_framework.shared;
package compiler.lib.ir_framework.driver.irmatching.mapping;
/**
* 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.
* Exception that is thrown if two {@link PhaseInterval} ranges overlap in {@link MultiPhaseRangeEntry}.
*
* @see PhaseInterval
* @see MultiPhaseRangeEntry
*/
class UnreachableCodeException extends RuntimeException {
public UnreachableCodeException() {
super("Unreachable code");
class OverlappingPhaseRangesException extends RuntimeException {
public OverlappingPhaseRangesException(PhaseInterval entry, PhaseInterval entry2) {
super("The following two PhaseRangeEntry objects overlap which is forbidden:" + System.lineSeparator() + "- "
+ entry + System.lineSeparator() + "- " + entry2);
}
}

View file

@ -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.mapping;
import compiler.lib.ir_framework.CompilePhase;
/**
* This class represents a compile phase interval/range on the ordering found in {@link CompilePhase}. The interval is
* defined as [start, end] (including start and end).
*
* @see CompilePhase
*/
public class PhaseInterval {
private final CompilePhase start;
private final CompilePhase end;
/**
* Create an interval that represents a singleton set (i.e. an interval that only contains a single compile phase).
*/
public PhaseInterval(CompilePhase singlePhase) {
this.start = singlePhase;
this.end = singlePhase;
}
public PhaseInterval(CompilePhase start, CompilePhase end) {
this.start = start;
this.end = end;
}
public int startIndex() {
return start.ordinal();
}
public int endIndex() {
return end.ordinal();
}
public CompilePhase start() {
return start;
}
public CompilePhase end() {
return end;
}
public boolean includes(CompilePhase phase) {
// start <= phase <= end
return phase.compareTo(start) >= 0 && phase.compareTo(end) <= 0;
}
@Override
public String toString() {
return "[" + start + ", " + end + "]";
}
}

View file

@ -0,0 +1,60 @@
/*
* 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.mapping;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.RegexType;
/**
* This class represents a mapping entry for an IR node that maps to a single regex for all compile phases whose
* {@link CompilePhase#regexType()} match the specified {@link RegexType} for this entry.
*/
public class RegexTypeEntry implements IRNodeMapEntry {
private final SingleRegexEntry singleRegexEntry;
private final RegexType regexType;
public RegexTypeEntry(RegexType regexType, String regex) {
this.regexType = regexType;
CompilePhase defaultCompilePhase = switch (regexType) {
case IDEAL_INDEPENDENT -> CompilePhase.PRINT_IDEAL;
case MACH -> CompilePhase.FINAL_CODE;
case OPTO_ASSEMBLY -> CompilePhase.PRINT_OPTO_ASSEMBLY;
};
this.singleRegexEntry = new SingleRegexEntry(defaultCompilePhase, regex);
}
@Override
public String regexForCompilePhase(CompilePhase compilePhase) {
if (compilePhase.regexType() == regexType) {
return singleRegexEntry.regex();
} else {
return null;
}
}
@Override
public CompilePhase defaultCompilePhase() {
return singleRegexEntry.defaultCompilePhase();
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.mapping;
import compiler.lib.ir_framework.CompilePhase;
/**
* This class represents a mapping entry for an IR node that is only applicable for a single compile phase. This phase
* also represents the default phase when the user specifies {@link CompilePhase#DEFAULT}.
*/
public class SinglePhaseEntry implements IRNodeMapEntry {
private final SingleRegexEntry singleRegexEntry;
public SinglePhaseEntry(CompilePhase defaultCompilePhase, String regex) {
this.singleRegexEntry = new SingleRegexEntry(defaultCompilePhase, regex);
}
@Override
public String regexForCompilePhase(CompilePhase compilePhase) {
if (compilePhase == defaultCompilePhase()) {
return singleRegexEntry.regex();
} else {
return null;
}
}
@Override
public CompilePhase defaultCompilePhase() {
return singleRegexEntry.defaultCompilePhase();
}
}

View file

@ -0,0 +1,60 @@
/*
* 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.mapping;
import compiler.lib.ir_framework.CompilePhase;
/**
* This class represents a mapping entry for an IR node that maps to a single regex for multiple continuous compile
* phases (i.e. follow each other immediately in the order defined in {@link CompilePhase}). This is done by providing
* a start and an end compile phase which is put into a {@link PhaseInterval}. An IR node mapping to different regexes
* for different intervals should use {@link MultiPhaseRangeEntry}.
*
* @see CompilePhase
* @see PhaseInterval
* @see MultiPhaseRangeEntry
*/
public class SinglePhaseRangeEntry implements IRNodeMapEntry {
private final SingleRegexEntry singleRegexEntry;
private final PhaseInterval interval;
public SinglePhaseRangeEntry(CompilePhase defaultCompilePhase, String regex, CompilePhase start, CompilePhase end) {
this.interval = new PhaseInterval(start, end);
this.singleRegexEntry = new SingleRegexEntry(defaultCompilePhase, regex);
}
@Override
public String regexForCompilePhase(CompilePhase compilePhase) {
if (interval.includes(compilePhase)) {
// start <= phase <= end
return singleRegexEntry.regex();
}
return null;
}
@Override
public CompilePhase defaultCompilePhase() {
return singleRegexEntry.defaultCompilePhase();
}
}

View file

@ -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.mapping;
import compiler.lib.ir_framework.CompilePhase;
/**
* This class represents a mapping entry for an IR node that maps to a single regex for multiple compile phases.
* If the IR node is only applicable to a single compile phase, a {@link SinglePhaseEntry} should be used.
*/
record SingleRegexEntry(CompilePhase defaultCompilePhase, String regex) {
}

View file

@ -24,21 +24,26 @@
package compiler.lib.ir_framework.driver.irmatching.parser;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.driver.irmatching.TestClass;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchable;
import compiler.lib.ir_framework.shared.TestFormat;
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.SortedSet;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 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}.
* Class to parse the ideal compile phases and PrintOptoAssembly outputs of the test class from the hotspot_pid* file
* of all methods collected by {@link IREncodingParser}.
*
* @see IRMethod
* @see IREncodingParser
@ -47,24 +52,29 @@ class HotSpotPidFileParser {
private static final Pattern COMPILE_ID_PATTERN = Pattern.compile("compile_id='(\\d+)'");
private final Pattern compileIdPatternForTestClass;
private Map<String, IRMethod> compilationsMap;
/**
* "Method name" -> TestMethod map created by {@link IREncodingParser} which contains an entry for each method that
* needs to be IR matched on.
*/
private final Map<String, TestMethod> testMethodMap;
public HotSpotPidFileParser(String testClass) {
public HotSpotPidFileParser(String testClass, Map<String, TestMethod> testMethodMap) {
this.compileIdPatternForTestClass = Pattern.compile("compile_id='(\\d+)'.*" + Pattern.quote(testClass) + " (\\S+)");
}
public void setCompilationsMap(Map<String, IRMethod> compilationsMap) {
this.compilationsMap = compilationsMap;
this.testMethodMap = testMethodMap;
}
/**
* 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).
* Parse the hotspot_pid*.log file from the test VM. Read the ideal compile phase and PrintOptoAssembly outputs for
* all methods defined by the IR encoding.
*/
public Collection<IRMethod> parseCompilations(String hotspotPidFileName) {
public TestClass parse(String hotspotPidFileName) {
try {
processFileLines(hotspotPidFileName);
return compilationsMap.values();
parseHotSpotFile(hotspotPidFileName);
SortedSet<IRMethodMatchable> irMethods = testMethodMap.values().stream()
.map(TestMethod::createIRMethod)
.collect(Collectors.toCollection(TreeSet::new));
TestFormat.throwIfAnyFailures();
return new TestClass(irMethods);
} catch (IOException e) {
throw new TestFrameworkException("Error while reading " + hotspotPidFileName, e);
} catch (FileCorruptedException e) {
@ -72,8 +82,8 @@ class HotSpotPidFileParser {
}
}
private void processFileLines(String hotspotPidFileName) throws IOException {
Map<Integer, IRMethod> compileIdMap = new HashMap<>();
private void parseHotSpotFile(String hotspotPidFileName) throws IOException {
Map<Integer, TestMethod> compileIdMap = new HashMap<>();
try (var reader = Files.newBufferedReader(Paths.get(hotspotPidFileName))) {
Line line = new Line(reader, compileIdPatternForTestClass);
BlockOutputReader blockOutputReader = new BlockOutputReader(reader, compileIdPatternForTestClass);
@ -87,22 +97,21 @@ class HotSpotPidFileParser {
}
}
private void processMethodBlock(Map<Integer, IRMethod> compileIdMap, Line line, BlockOutputReader blockOutputReader)
private void processMethodBlock(Map<Integer, TestMethod> compileIdMap, Line line, BlockOutputReader blockOutputReader)
throws IOException {
Block block = blockOutputReader.readBlock();
if (block.containsTestClassCompilations()) {
// Register all test method compilations that could have been emitted during a rare safepoint while
// dumping the PrintIdeal/PrintOptoAssembly output.
// dumping the ideal compile phase/PrintOptoAssembly output.
block.getTestClassCompilations().forEach(l -> parseTestMethodCompileId(compileIdMap, l));
}
setIRMethodOutput(block.getOutput(), line, compileIdMap);
}
private void parseTestMethodCompileId(Map<Integer, IRMethod> compileIdMap, String line) {
private void parseTestMethodCompileId(Map<Integer, TestMethod> compileIdMap, String line) {
String methodName = parseMethodName(line);
if (isTestAnnotatedMethod(methodName)) {
int compileId = getCompileId(line);
compileIdMap.put(compileId, getIrMethod(methodName));
compileIdMap.put(getCompileId(line), getTestMethod(methodName));
}
}
@ -116,11 +125,14 @@ class HotSpotPidFileParser {
* Is this a @Test method?
*/
private boolean isTestAnnotatedMethod(String testMethodName) {
return compilationsMap.containsKey(testMethodName);
return testMethodMap.containsKey(testMethodName);
}
private IRMethod getIrMethod(String testMethodName) {
return compilationsMap.get(testMethodName);
private TestMethod getTestMethod(String testMethodName) {
TestMethod testMethod = testMethodMap.get(testMethodName);
testMethod.clearOutput();
testMethod.setCompiled();
return testMethod;
}
private int getCompileId(String line) {
@ -134,24 +146,24 @@ class HotSpotPidFileParser {
/**
* Is this line the start of a PrintIdeal/PrintOptoAssembly output block of a @Test method?
*/
private boolean isTestMethodBlockStart(Line line, Map<Integer, IRMethod> compileIdMap) {
private boolean isTestMethodBlockStart(Line line, Map<Integer, TestMethod> compileIdMap) {
return line.isBlockStart() && isTestClassMethodBlock(line, compileIdMap);
}
private boolean isTestClassMethodBlock(Line line, Map<Integer, IRMethod> compileIdMap) {
private boolean isTestClassMethodBlock(Line line, Map<Integer, TestMethod> 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, Map<Integer, TestMethod> compileIdMap) {
TestMethod testMethod = compileIdMap.get(getCompileId(blockStartLine.getLine()));
setIRMethodOutput(blockOutput, blockStartLine, testMethod);
}
private void setIRMethodOutput(String blockOutput, Line blockStartLine, IRMethod irMethod) {
private void setIRMethodOutput(String blockOutput, Line blockStartLine, TestMethod testMethod) {
if (blockStartLine.isPrintIdealStart()) {
irMethod.setIdealOutput(blockOutput);
testMethod.setIdealOutput(blockOutput, blockStartLine.getCompilePhase());
} else {
irMethod.setOptoAssemblyOutput(blockOutput);
testMethod.setOptoAssemblyOutput(blockOutput);
}
}
}

View file

@ -25,7 +25,6 @@ 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;
@ -37,9 +36,9 @@ 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.
* Class to parse the IR encoding emitted by the test VM and creating {@link TestMethod} objects for each entry.
*
* @see IRMethod
* @see TestMethod
*/
class IREncodingParser {
@ -47,31 +46,36 @@ class IREncodingParser {
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 Map<String, TestMethod> testMethodMap;
private final Class<?> testClass;
public IREncodingParser(Class<?> testClass) {
this.testClass = testClass;
this.compilations = new HashMap<>();
this.testMethodMap = new HashMap<>();
}
public Map<String, IRMethod> parseIRMethods(String irEncoding) {
/**
* Parse the IR encoding passed as parameter and return a "test name" -> TestMethod map that contains an entry
* for each method that needs to be IR matched on.
*/
public Map<String, TestMethod> parse(String irEncoding) {
if (TestFramework.VERBOSE || PRINT_IR_ENCODING) {
System.out.println("Read IR encoding from test VM:");
System.out.println(irEncoding);
}
createCompilationsMap(irEncoding, testClass);
createTestMethodMap(irEncoding, testClass);
// We could have found format errors in @IR annotations. Report them now with an exception.
TestFormat.throwIfAnyFailures();
return compilations;
return testMethodMap;
}
/**
* Sets up a map testname -> IRMethod (containing the PrintIdeal and PrintOptoAssembly output for testname).
* Sets up a map testname -> TestMethod map. The TestMethod object will later be filled with the ideal and opto
* assembly output in {@link HotSpotPidFileParser}.
*/
private void createCompilationsMap(String irEncoding, Class<?> testClass) {
private void createTestMethodMap(String irEncoding, Class<?> testClass) {
Map<String, int[]> irRulesMap = parseIREncoding(irEncoding);
createIRMethodsWithEncoding(testClass, irRulesMap);
createTestMethodsWithEncoding(testClass, irRulesMap);
}
/**
@ -122,7 +126,7 @@ class IREncodingParser {
return irRulesIdx;
}
private void createIRMethodsWithEncoding(Class<?> testClass, Map<String, int[]> irRulesMap) {
private void createTestMethodsWithEncoding(Class<?> testClass, Map<String, int[]> irRulesMap) {
for (Method m : testClass.getDeclaredMethods()) {
IR[] irAnnos = m.getAnnotationsByType(IR.class);
if (irAnnos.length > 0) {
@ -130,7 +134,7 @@ class IREncodingParser {
int[] irRuleIds = irRulesMap.get(m.getName());
validateIRRuleIds(m, irAnnos, irRuleIds);
if (hasAnyApplicableIRRules(irRuleIds)) {
compilations.put(m.getName(), new IRMethod(m, irRuleIds, irAnnos));
testMethodMap.put(m.getName(), new TestMethod(m, irRuleIds));
}
}
}

View file

@ -23,6 +23,9 @@
package compiler.lib.ir_framework.driver.irmatching.parser;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.TestFramework;
import java.io.BufferedReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -31,6 +34,7 @@ import java.util.regex.Pattern;
* Class representing a normal line read from the hotspot_pid* file.
*/
class Line extends AbstractLine {
private static final Pattern IDEAL_COMPILE_PHASE_PATTERN = Pattern.compile("<ideal.*compile_phase='(.*)'>");
public Line(BufferedReader reader, Pattern compileIdPatternForTestClass) {
super(reader, compileIdPatternForTestClass);
}
@ -57,5 +61,11 @@ class Line extends AbstractLine {
// Ignore OSR compilations which have compile_kind set.
return line.startsWith("<opto_assembly") && notOSRCompilation();
}
}
public CompilePhase getCompilePhase() {
Matcher m = IDEAL_COMPILE_PHASE_PATTERN.matcher(line);
TestFramework.check(m.find(), "must always find \"compile_phase\" in ideal entry in " + line);
return CompilePhase.forName(m.group(1));
}
}

Some files were not shown because too many files have changed in this diff Show more