Skip to content

Commit 7d9ecf0

Browse files
committed
[GR-80584] Add empty-loop removal in low tier.
PullRequest: graal/25701
2 parents 0257002 + fe235fe commit 7d9ecf0

2 files changed

Lines changed: 97 additions & 0 deletions

File tree

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright (c) 2026, 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. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package jdk.graal.compiler.loop.test;
26+
27+
import org.junit.Assert;
28+
import org.junit.Test;
29+
30+
import jdk.graal.compiler.api.directives.GraalDirectives;
31+
import jdk.graal.compiler.core.test.GraalCompilerTest;
32+
import jdk.graal.compiler.loop.phases.AggressivePartialUnrollPhase;
33+
import jdk.graal.compiler.nodes.LoopBeginNode;
34+
import jdk.graal.compiler.nodes.StructuredGraph;
35+
import jdk.graal.compiler.options.OptionValues;
36+
import jdk.graal.compiler.vector.phases.VectorLoopUtility;
37+
38+
/**
39+
* Regression test for late empty-loop removal (GR-80584).
40+
*/
41+
public class LateRemoveEmptyLoopsTest extends GraalCompilerTest {
42+
43+
/**
44+
* Checks that the mid-tier graph contains a main loop.
45+
*/
46+
@Override
47+
protected void checkMidTierGraph(StructuredGraph graph) {
48+
super.checkMidTierGraph(graph);
49+
boolean hasMainLoop = false;
50+
for (LoopBeginNode loop : graph.getNodes(LoopBeginNode.TYPE)) {
51+
hasMainLoop |= loop.isMainLoop();
52+
}
53+
Assert.assertTrue("expected main loop in mid-tier graph", hasMainLoop);
54+
}
55+
56+
/**
57+
* Checks that the low-tier graph contains no main loop.
58+
*/
59+
@Override
60+
protected void checkLowTierGraph(StructuredGraph graph) {
61+
super.checkLowTierGraph(graph);
62+
for (LoopBeginNode loop : graph.getNodes(LoopBeginNode.TYPE)) {
63+
Assert.assertFalse("unexpected main loop: " + loop, loop.isMainLoop());
64+
}
65+
}
66+
67+
/**
68+
* Sets {@code state} to 1 on odd iterations.
69+
*
70+
* @param limit the exclusive loop bound
71+
* @param initial the initial state
72+
* @return {@code initial} if {@code limit <= 1}, otherwise 1
73+
*/
74+
public static int alternatingState(int limit, int initial) {
75+
int state = initial;
76+
for (int i = 0; GraalDirectives.injectIterationCount(1_000_000, i < limit); i++) {
77+
if (GraalDirectives.injectBranchProbability(0.5, (i & 1) != 0)) {
78+
state = 1;
79+
}
80+
}
81+
return state;
82+
}
83+
84+
/**
85+
* Checks the result and absence of main loops.
86+
*/
87+
@Test
88+
public void testAlternatingState() {
89+
OptionValues options = new OptionValues(getInitialOptions(),
90+
AggressivePartialUnrollPhase.Options.HighTierPartialUnrolling, false,
91+
VectorLoopUtility.Options.RespectVectorization, false);
92+
test(options, "alternatingState", 20, 23);
93+
}
94+
}

‎compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/LowTier.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import jdk.graal.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
5757
import jdk.graal.compiler.phases.tiers.LowTierContext;
5858
import jdk.graal.compiler.vector.phases.VectorLoweringPhaseSuite;
59+
import jdk.graal.compiler.vector.phases.RemoveEmptyLoopsPhase;
5960
import jdk.graal.compiler.vector.replacements.VectorIntrinsics;
6061
import jdk.graal.compiler.virtual.phases.ea.LowTierReadEliminationPhase;
6162

@@ -121,6 +122,8 @@ public LowTier(OptionValues options) {
121122

122123
appendPhase(canonicalizerWithoutGVN);
123124

125+
appendPhase(new RemoveEmptyLoopsPhase(canonicalizerWithoutGVN));
126+
124127
/*
125128
* This placeholder should be replaced by an instance of {@link AddressLoweringPhase}
126129
* specific to the target architecture for this compilation. This should be done by the

0 commit comments

Comments
 (0)