Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ public class IRNode {
private static final String START = "(\\d+(\\s){2}(";
private static final String MID = ".*)+(\\s){2}===.*";
private static final String END = ")";
private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END;
private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END;

public static final String IS_REPLACED = "#IS_REPLACED#"; // Is replaced by an additional user-defined string.

Expand Down Expand Up @@ -2938,13 +2936,25 @@ private static void parsePredicateNodes(String irNodePlaceholder, String label)
CompilePhase.AFTER_LOOP_OPTS));
}

// Typename in load/store have the structure:
// @fully/qualified/package/name/to/TheClass+12 *
// And variation:
// - after @, we can have "stable:" or other labels, with optional space after ':'
// - the class can actually be a subclass, with $ separator (and it must be ok to give only the deepest one
// - after the class name, we can have a comma-separated list of implemented interfaces enclosed in parentheses
// - before the offset, we can have something like ":NotNull", either way, seeing "+" or ":" means the end of the type
// Worst case, it can be something like:
// @bla: bli:a/b/c$d$e (f/g,h/i/j):NotNull+24 *
private static final String LOAD_STORE_PREFIX = "@(\\w+: ?)*[\\w/\\$]*\\b";
private static final String LOAD_STORE_SUFFIX = "( \\([^\\)]+\\))?(:|\\+)\\S* \\*";

private static void loadOfNodes(String irNodePlaceholder, String irNodeRegex) {
String regex = START + irNodeRegex + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
String regex = START + irNodeRegex + MID + LOAD_STORE_PREFIX + IS_REPLACED + LOAD_STORE_SUFFIX + END;
beforeMatching(irNodePlaceholder, regex);
}

private static void storeOfNodes(String irNodePlaceholder, String irNodeRegex) {
String regex = START + irNodeRegex + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX;
String regex = START + irNodeRegex + MID + LOAD_STORE_PREFIX + IS_REPLACED + LOAD_STORE_SUFFIX + END;
beforeMatching(irNodePlaceholder, regex);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class TestPhaseIRMatching {
public static void main(String[] args) {
run(Basics.class);
run(NoCompilationOutput.class);
run(LoadStore.class);
}

private static void run(Class<?> testClass) {
Expand Down Expand Up @@ -549,3 +550,239 @@ public static List<Failure> sort(Set<Failure> failures) {
.thenComparing(Failure::constraintId)).collect(Collectors.toList());
}
}

// Test load and store regexes
class LoadStore {
int i;
float f;
interface I1 {}
static class Base implements I1 {
int i;
}
interface I2 {}
static class Derived extends Base implements I2 {
long l;
}
Base base = new Base();
Derived derived = new Derived();

static class SingleNest {
static class DoubleNest {
int i;
}
}

SingleNest.DoubleNest doubleNest = new SingleNest.DoubleNest();


@Test
@IR(failOn = {IRNode.LOAD_OF_CLASS, ".*", IRNode.STORE_OF_CLASS, ".*"})
public void triviallyFailBoth() {
}

@Test
@IR(counts = {
IRNode.LOAD_OF_CLASS, "LoadS[a-z]+", "1",
IRNode.LOAD_OF_CLASS, "Load.tore", "1",
IRNode.LOAD_OF_CLASS, "LoadStore", "1",
IRNode.LOAD_OF_CLASS, "/LoadStore", "1",
IRNode.LOAD_OF_CLASS, "tests/LoadStore", "1",
IRNode.LOAD_OF_CLASS, "/tests/LoadStore", "1",
IRNode.LOAD_OF_CLASS, "ir_framework/tests/LoadStore", "1",
IRNode.LOAD_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore", "1", // To assert it's the whole qualification
IRNode.LOAD_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1",
},
failOn = {
IRNode.LOAD_OF_CLASS, "oadStore",
IRNode.LOAD_OF_CLASS, "LoadStor",
IRNode.LOAD_OF_CLASS, "/ir_framework/tests/LoadStore",
IRNode.LOAD_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*",
}
)
// @ir_framework/tests/LoadStore+12 *
public float simpleLoad() {
return f;
}

@Test
@IR(counts = {
IRNode.STORE_OF_CLASS, "LoadS[a-z]+", "1",
IRNode.STORE_OF_CLASS, "Load.tore", "1",
IRNode.STORE_OF_CLASS, "LoadStore", "1",
IRNode.STORE_OF_CLASS, "/LoadStore", "1",
IRNode.STORE_OF_CLASS, "tests/LoadStore", "1",
IRNode.STORE_OF_CLASS, "/tests/LoadStore", "1",
IRNode.STORE_OF_CLASS, "ir_framework/tests/LoadStore", "1",
IRNode.STORE_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore", "1",
IRNode.STORE_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1",
},
failOn = {
IRNode.STORE_OF_CLASS, "oadStore",
IRNode.STORE_OF_CLASS, "LoadStor",
IRNode.STORE_OF_CLASS, "/ir_framework/tests/LoadStore",
IRNode.STORE_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*",
}
)
// @ir_framework/tests/LoadStore+12 *
public void simpleStore() {
i = 1;
}

@Test
@IR(counts = {
IRNode.LOAD_I_OF_CLASS, "Base", "1",
IRNode.LOAD_I_OF_CLASS, "\\$Base", "1",
IRNode.LOAD_I_OF_CLASS, "LoadS[a-z]+\\$Base", "1",
IRNode.LOAD_I_OF_CLASS, "Load.tore\\$Base", "1",
IRNode.LOAD_I_OF_CLASS, "LoadStore\\$Base", "1",
IRNode.LOAD_I_OF_CLASS, "/LoadStore\\$Base", "1",
IRNode.LOAD_I_OF_CLASS, "tests/LoadStore\\$Base", "1",
IRNode.LOAD_I_OF_CLASS, "/tests/LoadStore\\$Base", "1",
IRNode.LOAD_I_OF_CLASS, "ir_framework/tests/LoadStore\\$Base", "1",
IRNode.LOAD_I_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore\\$Base", "1",
IRNode.LOAD_I_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1",
},
failOn = {
IRNode.LOAD_I_OF_CLASS, "/Base",
IRNode.LOAD_I_OF_CLASS, "oadStore\\$Base",
IRNode.LOAD_I_OF_CLASS, "LoadStore\\$Bas",
IRNode.LOAD_I_OF_CLASS, "LoadStore",
IRNode.LOAD_I_OF_CLASS, "/ir_framework/tests/LoadStore\\$Base",
IRNode.LOAD_I_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*",
}
)
// @ir_framework/tests/LoadStore$Base (ir_framework/tests/LoadStore$I1)+12 *
public int loadWithInterface() {
return base.i;
}

@Test
@IR(counts = {
IRNode.STORE_I_OF_CLASS, "Base", "1",
IRNode.STORE_I_OF_CLASS, "\\$Base", "1",
IRNode.STORE_I_OF_CLASS, "LoadS[a-z]+\\$Base", "1",
IRNode.STORE_I_OF_CLASS, "Load.tore\\$Base", "1",
IRNode.STORE_I_OF_CLASS, "LoadStore\\$Base", "1",
IRNode.STORE_I_OF_CLASS, "/LoadStore\\$Base", "1",
IRNode.STORE_I_OF_CLASS, "tests/LoadStore\\$Base", "1",
IRNode.STORE_I_OF_CLASS, "/tests/LoadStore\\$Base", "1",
IRNode.STORE_I_OF_CLASS, "ir_framework/tests/LoadStore\\$Base", "1",
IRNode.STORE_I_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore\\$Base", "1",
IRNode.STORE_I_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1",
},
failOn = {
IRNode.STORE_I_OF_CLASS, "/Base",
IRNode.STORE_I_OF_CLASS, "oadStore\\$Base",
IRNode.STORE_I_OF_CLASS, "LoadStore\\$Bas",
IRNode.STORE_I_OF_CLASS, "LoadStore",
IRNode.STORE_I_OF_CLASS, "/ir_framework/tests/LoadStore\\$Base",
IRNode.STORE_I_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*",
}
)
// @ir_framework/tests/LoadStore$Base (ir_framework/tests/LoadStore$I1)+12 *
public void storeWithInterface() {
base.i = 1;
}

@Test
@IR(counts = {
IRNode.LOAD_L_OF_CLASS, "Derived", "1",
IRNode.LOAD_L_OF_CLASS, "\\$Derived", "1",
IRNode.LOAD_L_OF_CLASS, "LoadS[a-z]+\\$Derived", "1",
IRNode.LOAD_L_OF_CLASS, "Load.tore\\$Derived", "1",
IRNode.LOAD_L_OF_CLASS, "LoadStore\\$Derived", "1",
IRNode.LOAD_L_OF_CLASS, "/LoadStore\\$Derived", "1",
IRNode.LOAD_L_OF_CLASS, "tests/LoadStore\\$Derived", "1",
IRNode.LOAD_L_OF_CLASS, "/tests/LoadStore\\$Derived", "1",
IRNode.LOAD_L_OF_CLASS, "ir_framework/tests/LoadStore\\$Derived", "1",
IRNode.LOAD_L_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore\\$Derived", "1",
IRNode.LOAD_L_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1",
},
failOn = {
IRNode.LOAD_L_OF_CLASS, "/Derived",
IRNode.LOAD_L_OF_CLASS, "oadStore\\$Derived",
IRNode.LOAD_L_OF_CLASS, "LoadStore\\$Derive",
IRNode.LOAD_L_OF_CLASS, "LoadStore",
IRNode.LOAD_L_OF_CLASS, "/ir_framework/tests/LoadStore\\$Derived",
IRNode.LOAD_L_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*",
}
)
// @ir_framework/tests/LoadStore$Derived (ir_framework/tests/LoadStore$I1,ir_framework/tests/LoadStore$I2)+24 *
public long loadWithInterfaces() {
return derived.l;
}

@Test
@IR(counts = {
IRNode.STORE_L_OF_CLASS, "Derived", "1",
IRNode.STORE_L_OF_CLASS, "\\$Derived", "1",
IRNode.STORE_L_OF_CLASS, "LoadS[a-z]+\\$Derived", "1",
IRNode.STORE_L_OF_CLASS, "Load.tore\\$Derived", "1",
IRNode.STORE_L_OF_CLASS, "LoadStore\\$Derived", "1",
IRNode.STORE_L_OF_CLASS, "/LoadStore\\$Derived", "1",
IRNode.STORE_L_OF_CLASS, "tests/LoadStore\\$Derived", "1",
IRNode.STORE_L_OF_CLASS, "/tests/LoadStore\\$Derived", "1",
IRNode.STORE_L_OF_CLASS, "ir_framework/tests/LoadStore\\$Derived", "1",
IRNode.STORE_L_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore\\$Derived", "1",
IRNode.STORE_L_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1",
},
failOn = {
IRNode.STORE_L_OF_CLASS, "/Derived",
IRNode.STORE_L_OF_CLASS, "oadStore\\$Derived",
IRNode.STORE_L_OF_CLASS, "LoadStore\\$Derive",
IRNode.STORE_L_OF_CLASS, "LoadStore",
IRNode.STORE_L_OF_CLASS, "/ir_framework/tests/LoadStore\\$Derived",
IRNode.STORE_L_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*",
}
)
// @ir_framework/tests/LoadStore$Derived (ir_framework/tests/LoadStore$I1,ir_framework/tests/LoadStore$I2)+24 *
public void storeWithInterfaces() {
derived.l = 1;
}

@Test
@IR(counts = {
IRNode.LOAD_I_OF_CLASS, "DoubleNest", "1",
IRNode.LOAD_I_OF_CLASS, "\\$DoubleNest", "1",
IRNode.LOAD_I_OF_CLASS, "SingleNest\\$DoubleNest", "1",
IRNode.LOAD_I_OF_CLASS, "\\$SingleNest\\$DoubleNest", "1",
IRNode.LOAD_I_OF_CLASS, "LoadStore\\$SingleNest\\$DoubleNest", "1",
IRNode.LOAD_I_OF_CLASS, "/LoadStore\\$SingleNest\\$DoubleNest", "1",
IRNode.LOAD_I_OF_CLASS, "tests/LoadStore\\$SingleNest\\$DoubleNest", "1",
IRNode.LOAD_I_OF_CLASS, "/tests/LoadStore\\$SingleNest\\$DoubleNest", "1",
IRNode.LOAD_I_OF_CLASS, "ir_framework/tests/LoadStore\\$SingleNest\\$DoubleNest", "1",
},
failOn = {
IRNode.LOAD_I_OF_CLASS, "SingleNest",
IRNode.LOAD_I_OF_CLASS, "LoadStore",
IRNode.LOAD_I_OF_CLASS, "LoadStore\\$SingleNest",
}
)
// @ir_framework/tests/LoadStore$SingleNest$DoubleNest+12 *
public int loadDoubleNested() {
return doubleNest.i;
}

@Test
@IR(counts = {
IRNode.STORE_I_OF_CLASS, "DoubleNest", "1",
IRNode.STORE_I_OF_CLASS, "\\$DoubleNest", "1",
IRNode.STORE_I_OF_CLASS, "SingleNest\\$DoubleNest", "1",
IRNode.STORE_I_OF_CLASS, "\\$SingleNest\\$DoubleNest", "1",
IRNode.STORE_I_OF_CLASS, "LoadStore\\$SingleNest\\$DoubleNest", "1",
IRNode.STORE_I_OF_CLASS, "/LoadStore\\$SingleNest\\$DoubleNest", "1",
IRNode.STORE_I_OF_CLASS, "tests/LoadStore\\$SingleNest\\$DoubleNest", "1",
IRNode.STORE_I_OF_CLASS, "/tests/LoadStore\\$SingleNest\\$DoubleNest", "1",
IRNode.STORE_I_OF_CLASS, "ir_framework/tests/LoadStore\\$SingleNest\\$DoubleNest", "1",
},
failOn = {
IRNode.STORE_I_OF_CLASS, "SingleNest",
IRNode.STORE_I_OF_CLASS, "LoadStore",
IRNode.STORE_I_OF_CLASS, "LoadStore\\$SingleNest",
}
)
// @ir_framework/tests/LoadStore$SingleNest$DoubleNest+12 *
public void storeDoubleNested() {
doubleNest.i = 1;
}
}