Skip to content

Commit d358f5f

Browse files
mhaessigchhagedorn
authored andcommitted
8347449: C2: UseLoopPredicate off should also turn UseProfiledLoopPredicate off
Reviewed-by: chagedorn, epeter
1 parent f301663 commit d358f5f

File tree

7 files changed

+148
-22
lines changed

7 files changed

+148
-22
lines changed

src/hotspot/share/opto/c2_globals.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -238,7 +238,7 @@
238238
"Force counted loops to keep a safepoint") \
239239
\
240240
product(bool, UseLoopPredicate, true, \
241-
"Generate a predicate to select fast/slow loop versions") \
241+
"Move checks with uncommon trap out of loops.") \
242242
\
243243
develop(bool, TraceLoopPredicate, false, \
244244
"Trace generation of loop predicates") \
@@ -785,7 +785,9 @@
785785
range(0, max_juint) \
786786
\
787787
product(bool, UseProfiledLoopPredicate, true, \
788-
"Move predicates out of loops based on profiling data") \
788+
"Move checks with an uncommon trap out of loops based on " \
789+
"profiling data. " \
790+
"Requires UseLoopPredicate to be turned on (default).") \
789791
\
790792
develop(uintx, StressLongCountedLoop, 0, \
791793
"if > 0, convert int counted loops to long counted loops" \

src/hotspot/share/opto/graphKit.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4037,9 +4037,9 @@ void GraphKit::add_parse_predicate(Deoptimization::DeoptReason reason, const int
40374037
void GraphKit::add_parse_predicates(int nargs) {
40384038
if (UseLoopPredicate) {
40394039
add_parse_predicate(Deoptimization::Reason_predicate, nargs);
4040-
}
4041-
if (UseProfiledLoopPredicate) {
4042-
add_parse_predicate(Deoptimization::Reason_profile_predicate, nargs);
4040+
if (UseProfiledLoopPredicate) {
4041+
add_parse_predicate(Deoptimization::Reason_profile_predicate, nargs);
4042+
}
40434043
}
40444044
add_parse_predicate(Deoptimization::Reason_auto_vectorization_check, nargs);
40454045
// Loop Limit Check Predicate should be near the loop.

src/hotspot/share/opto/idealKit.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,12 @@ void IdealKit::end_if() {
163163
// onto the stack.
164164
void IdealKit::loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) {
165165
assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new loop");
166-
if (UseLoopPredicate) {
167-
// Sync IdealKit and graphKit.
168-
gkit->sync_kit(*this);
169-
// Add Parse Predicates.
170-
gkit->add_parse_predicates(nargs);
171-
// Update IdealKit memory.
172-
sync_kit(gkit);
173-
}
166+
// Sync IdealKit and graphKit.
167+
gkit->sync_kit(*this);
168+
// Add Parse Predicates.
169+
gkit->add_parse_predicates(nargs);
170+
// Update IdealKit memory.
171+
sync_kit(gkit);
174172
set(iv, init);
175173
Node* head = make_label(1);
176174
bind(head);

src/hotspot/share/opto/loopnode.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,9 +1087,9 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) {
10871087

10881088
if (UseLoopPredicate) {
10891089
add_parse_predicate(Deoptimization::Reason_predicate, inner_head, outer_ilt, cloned_sfpt);
1090-
}
1091-
if (UseProfiledLoopPredicate) {
1092-
add_parse_predicate(Deoptimization::Reason_profile_predicate, inner_head, outer_ilt, cloned_sfpt);
1090+
if (UseProfiledLoopPredicate) {
1091+
add_parse_predicate(Deoptimization::Reason_profile_predicate, inner_head, outer_ilt, cloned_sfpt);
1092+
}
10931093
}
10941094

10951095
// We only want to use the auto-vectorization check as a trap once per bci. And
@@ -4298,11 +4298,13 @@ void IdealLoopTree::dump_head() {
42984298
if (predicates.loop_limit_check_predicate_block()->is_non_empty()) {
42994299
tty->print(" limit_check");
43004300
}
4301-
if (UseProfiledLoopPredicate && predicates.profiled_loop_predicate_block()->is_non_empty()) {
4302-
tty->print(" profile_predicated");
4303-
}
4304-
if (UseLoopPredicate && predicates.loop_predicate_block()->is_non_empty()) {
4305-
tty->print(" predicated");
4301+
if (UseLoopPredicate) {
4302+
if (UseProfiledLoopPredicate && predicates.profiled_loop_predicate_block()->is_non_empty()) {
4303+
tty->print(" profile_predicated");
4304+
}
4305+
if (predicates.loop_predicate_block()->is_non_empty()) {
4306+
tty->print(" predicated");
4307+
}
43064308
}
43074309
if (_head->is_CountedLoop()) {
43084310
CountedLoopNode *cl = _head->as_CountedLoop();

src/hotspot/share/runtime/arguments.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3797,6 +3797,13 @@ jint Arguments::apply_ergo() {
37973797
}
37983798
#endif // COMPILER2_OR_JVMCI
37993799

3800+
#ifdef COMPILER2
3801+
if (!FLAG_IS_DEFAULT(UseLoopPredicate) && !UseLoopPredicate && UseProfiledLoopPredicate) {
3802+
warning("Disabling UseProfiledLoopPredicate since UseLoopPredicate is turned off.");
3803+
FLAG_SET_ERGO(UseProfiledLoopPredicate, false);
3804+
}
3805+
#endif // COMPILER2
3806+
38003807
if (log_is_enabled(Info, perf, class, link)) {
38013808
if (!UsePerfData) {
38023809
warning("Disabling -Xlog:perf+class+link since UsePerfData is turned off.");

test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,21 @@ public class IRNode {
15391539
CompilePhase.BEFORE_MATCHING));
15401540
}
15411541

1542+
public static final String LOOP_PARSE_PREDICATE = PREFIX + "LOOP_PARSE_PREDICATE" + POSTFIX;
1543+
static {
1544+
parsePredicateNodes(LOOP_PARSE_PREDICATE, "Loop");
1545+
}
1546+
1547+
public static final String LOOP_LIMIT_CHECK_PARSE_PREDICATE = PREFIX + "LOOP_LIMIT_CHECK_PARSE_PREDICATE" + POSTFIX;
1548+
static {
1549+
parsePredicateNodes(LOOP_LIMIT_CHECK_PARSE_PREDICATE, "Loop Limit Check");
1550+
}
1551+
1552+
public static final String PROFILED_LOOP_PARSE_PREDICATE = PREFIX + "PROFILED_LOOP_PARSE_PREDICATE" + POSTFIX;
1553+
static {
1554+
parsePredicateNodes(PROFILED_LOOP_PARSE_PREDICATE, "Profiled Loop");
1555+
}
1556+
15421557
public static final String PREDICATE_TRAP = PREFIX + "PREDICATE_TRAP" + POSTFIX;
15431558
static {
15441559
trapNodes(PREDICATE_TRAP, "predicate");
@@ -2761,6 +2776,13 @@ private static void trapNodes(String irNodePlaceholder, String trapReason) {
27612776
beforeMatching(irNodePlaceholder, regex);
27622777
}
27632778

2779+
private static void parsePredicateNodes(String irNodePlaceholder, String label) {
2780+
String regex = START + "ParsePredicate" + MID + "#" + label + "[ ]*!jvms:" + END;
2781+
IR_NODE_MAPPINGS.put(irNodePlaceholder, new SinglePhaseRangeEntry(CompilePhase.AFTER_PARSING, regex,
2782+
CompilePhase.AFTER_PARSING,
2783+
CompilePhase.PHASEIDEALLOOP_ITERATIONS));
2784+
}
2785+
27642786
private static void loadOfNodes(String irNodePlaceholder, String irNodeRegex) {
27652787
String regex = START + irNodeRegex + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
27662788
beforeMatching(irNodePlaceholder, regex);
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
25+
package compiler.predicates;
26+
27+
import compiler.lib.ir_framework.*;
28+
import jdk.test.lib.Asserts;
29+
30+
/*
31+
* @test
32+
* @bug 8347449
33+
* @summary Test that profiled loop predicates are turned off if loop predicates are turned off
34+
* @library /test/lib /
35+
* @run driver compiler.predicates.TestDisabledLoopPredicates
36+
*/
37+
38+
public class TestDisabledLoopPredicates {
39+
static final int SIZE = 100;
40+
static final int MIN = 3;
41+
42+
public static void main(String[] args) {
43+
TestFramework.runWithFlags("-XX:+UseLoopPredicate",
44+
"-XX:+UseProfiledLoopPredicate");
45+
TestFramework.runWithFlags("-XX:-UseLoopPredicate");
46+
TestFramework.runWithFlags("-XX:-UseProfiledLoopPredicate");
47+
}
48+
49+
@Run(test = "test")
50+
private static void check() {
51+
int res = test(true);
52+
Asserts.assertEQ(res, ((SIZE - 1) * SIZE - MIN * (MIN + 1)) / 2);
53+
}
54+
55+
@DontInline
56+
private static void blackhole(int i) {
57+
}
58+
59+
@DontInline
60+
private static int[] getArr() {
61+
int[] arr = new int[SIZE];
62+
for (int i = 0; i < SIZE; i++) {
63+
arr[i] = i;
64+
}
65+
66+
return arr;
67+
}
68+
69+
@Test
70+
@IR(counts = { IRNode.LOOP_PARSE_PREDICATE, "1",
71+
IRNode.PROFILED_LOOP_PARSE_PREDICATE, "1" },
72+
applyIfAnd = { "UseLoopPredicate", "true",
73+
"UseProfiledLoopPredicate", "true" })
74+
@IR(failOn = { IRNode.LOOP_PARSE_PREDICATE,
75+
IRNode.PROFILED_LOOP_PARSE_PREDICATE },
76+
applyIf = { "UseLoopPredicate", "false" })
77+
@IR(counts = { IRNode.LOOP_PARSE_PREDICATE, "1" },
78+
failOn = { IRNode.PROFILED_LOOP_PARSE_PREDICATE },
79+
applyIfAnd = { "UseLoopPredicate", "true",
80+
"UseProfiledLoopPredicate", "false" })
81+
public static int test(boolean cond) {
82+
int[] arr = getArr();
83+
int sum = 0;
84+
for (int i = 0; i < arr.length; i++) {
85+
if (cond) {
86+
if (arr[i] > MIN) {
87+
sum += arr[i];
88+
}
89+
}
90+
blackhole(arr[i]);
91+
}
92+
93+
return sum;
94+
}
95+
}

0 commit comments

Comments
 (0)