8372646: C2: Stress Counted Loop creation

Reviewed-by: rcastanedalo, chagedorn, dfenacci
This commit is contained in:
Saranya Natarajan 2026-03-25 12:47:41 +00:00
parent 3737cad6d9
commit 46e6b26bf8
3 changed files with 25 additions and 5 deletions

View File

@ -907,6 +907,9 @@
\
develop(bool, StressLoopPeeling, false, \
"Randomize loop peeling decision") \
\
develop(bool, StressCountedLoop, false, \
"Randomly delay conversion to counted loops") \
// end of C2_FLAGS

View File

@ -741,7 +741,7 @@ Compile::Compile(ciEnv* ci_env, ciMethod* target, int osr_bci,
if (StressLCM || StressGCM || StressIGVN || StressCCP ||
StressIncrementalInlining || StressMacroExpansion ||
StressMacroElimination || StressUnstableIfTraps ||
StressBailout || StressLoopPeeling) {
StressBailout || StressLoopPeeling || StressCountedLoop) {
initialize_stress_seed(directive);
}
@ -2257,7 +2257,9 @@ bool Compile::optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode) {
PhaseIdealLoop::optimize(igvn, mode);
_loop_opts_cnt--;
if (failing()) return false;
if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2);
if (major_progress()) {
print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2);
}
}
}
return true;
@ -3798,7 +3800,11 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
}
break;
case Op_Loop:
assert(!n->as_Loop()->is_loop_nest_inner_loop() || _loop_opts_cnt == 0, "should have been turned into a counted loop");
// When StressCountedLoop is enabled, this loop may intentionally avoid a counted loop conversion.
// This is expected behavior for the stress mode, which exercises alternative compilation paths.
if (!StressCountedLoop) {
assert(!n->as_Loop()->is_loop_nest_inner_loop() || _loop_opts_cnt == 0, "should have been turned into a counted loop");
}
case Op_CountedLoop:
case Op_LongCountedLoop:
case Op_OuterStripMinedLoop:

View File

@ -2137,7 +2137,6 @@ bool CountedLoopConverter::is_counted_loop() {
}
assert(_head->Opcode() == Op_Loop || _head->Opcode() == Op_LongCountedLoop, "regular loops only");
_phase->C->print_method(PHASE_BEFORE_CLOOPS, 3, _head);
// ===================================================
// We can only convert this loop to a counted loop if we can guarantee that the iv phi will never overflow at runtime.
@ -2411,6 +2410,12 @@ bool CountedLoopConverter::is_counted_loop() {
_checked_for_counted_loop = true;
#endif
#ifndef PRODUCT
if (StressCountedLoop && (_phase->C->random() % 2 == 0)) {
return false;
}
#endif
return true;
}
@ -2553,6 +2558,8 @@ IdealLoopTree* CountedLoopConverter::convert() {
PhaseIterGVN* igvn = &_phase->igvn();
_phase->C->print_method(PHASE_BEFORE_CLOOPS, 3, _head);
if (_should_insert_stride_overflow_limit_check) {
insert_stride_overflow_limit_check();
}
@ -4734,7 +4741,11 @@ void IdealLoopTree::counted_loop( PhaseIdealLoop *phase ) {
} else if (_head->is_LongCountedLoop() || phase->try_convert_to_counted_loop(_head, loop, T_LONG)) {
remove_safepoints(phase, true);
} else {
assert(!_head->is_Loop() || !_head->as_Loop()->is_loop_nest_inner_loop(), "transformation to counted loop should not fail");
// When StressCountedLoop is enabled, this loop may intentionally avoid a counted loop conversion.
// This is expected behavior for the stress mode, which exercises alternative compilation paths.
if (!StressCountedLoop) {
assert(!_head->is_Loop() || !_head->as_Loop()->is_loop_nest_inner_loop(), "transformation to counted loop should not fail");
}
if (_parent != nullptr && !_irreducible) {
// Not a counted loop. Keep one safepoint.
bool keep_one_sfpt = true;