1
1
/*
2
- * Copyright (c) 2013, 2022 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2013, 2025 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
33
33
import jdk .graal .compiler .nodes .AbstractBeginNode ;
34
34
import jdk .graal .compiler .nodes .BeginNode ;
35
35
import jdk .graal .compiler .nodes .DeoptimizeNode ;
36
+ import jdk .graal .compiler .nodes .FixedGuardNode ;
36
37
import jdk .graal .compiler .nodes .FixedWithNextNode ;
37
38
import jdk .graal .compiler .nodes .GraphState ;
38
39
import jdk .graal .compiler .nodes .GraphState .GuardsStage ;
50
51
import jdk .graal .compiler .phases .schedule .SchedulePhase ;
51
52
52
53
/**
53
- * This phase lowers {@link GuardNode GuardNodes} into corresponding control-flow structure and
54
- * {@link DeoptimizeNode DeoptimizeNodes}.
54
+ * This phase lowers {@link GuardNode floating GuardNodes} and {@link FixedGuardNode}s into
55
+ * corresponding control-flow structure and {@link DeoptimizeNode DeoptimizeNodes}.
56
+ * <p/>
57
+ *
58
+ * This allows compilation to enter the {@link GuardsStage#FIXED_DEOPTS FIXED_DEOPTS} stage of the
59
+ * graph where all nodes that may cause deoptimization are fixed.
60
+ * <p/>
55
61
*
56
- * This allow to enter the {@link GuardsStage#FIXED_DEOPTS FIXED_DEOPTS} stage of the graph where
57
- * all node that may cause deoptimization are fixed.
58
- * <p>
59
62
* It first makes a schedule in order to know where the control flow should be placed. Then, for
60
63
* each block, it applies two passes. The first one tries to replace null-check guards with implicit
61
64
* null checks performed by access to the objects that need to be null checked. The second phase
@@ -113,23 +116,44 @@ private void lowerToIf(GuardNode guard) {
113
116
}
114
117
}
115
118
119
+ @ Override
120
+ public boolean shouldApply (StructuredGraph graph ) {
121
+ return graph .hasNode (GuardNode .TYPE ) || graph .hasNode (FixedGuardNode .TYPE );
122
+ }
123
+
116
124
@ Override
117
125
public Optional <NotApplicable > notApplicableTo (GraphState graphState ) {
118
126
return NotApplicable .ifAny (
119
127
NotApplicable .ifApplied (this , StageFlag .GUARD_LOWERING , graphState ),
120
128
NotApplicable .when (!graphState .getGuardsStage ().allowsFloatingGuards (), "Floating guards must be allowed" ));
121
129
}
122
130
123
- @ Override
124
- protected void run (StructuredGraph graph , CoreProviders context ) {
131
+ private static void lowerFloatingGuards (StructuredGraph graph ) {
125
132
SchedulePhase .runWithoutContextOptimizations (graph , SchedulePhase .SchedulingStrategy .EARLIEST_WITH_GUARD_ORDER );
126
133
ScheduleResult schedule = graph .getLastSchedule ();
127
134
128
135
for (HIRBlock block : schedule .getCFG ().getBlocks ()) {
129
136
processBlock (block , schedule );
130
137
}
138
+ }
131
139
132
- assert assertNoGuardsLeft (graph );
140
+ private static void lowerFixedGuards (StructuredGraph graph ) {
141
+ for (FixedGuardNode fixedGuard : graph .getNodes (FixedGuardNode .TYPE )) {
142
+ fixedGuard .lowerToIf ();
143
+ }
144
+ }
145
+
146
+ @ Override
147
+ protected void run (StructuredGraph graph , CoreProviders context ) {
148
+ if (graph .hasNode (GuardNode .TYPE )) {
149
+ lowerFloatingGuards (graph );
150
+ }
151
+ if (graph .hasNode (FixedGuardNode .TYPE )) {
152
+ lowerFixedGuards (graph );
153
+ }
154
+
155
+ assert graph .getNodes (GuardNode .TYPE ).isEmpty () : "no floating guards must be left after guard lowering" ;
156
+ assert graph .getNodes (FixedGuardNode .TYPE ).isEmpty () : "no fixed guards must be left after guard lowering" ;
133
157
}
134
158
135
159
@ Override
@@ -139,11 +163,6 @@ public void updateGraphState(GraphState graphState) {
139
163
graphState .setGuardsStage (GuardsStage .FIXED_DEOPTS );
140
164
}
141
165
142
- private static boolean assertNoGuardsLeft (StructuredGraph graph ) {
143
- assert graph .getNodes (GuardNode .TYPE ).isEmpty ();
144
- return true ;
145
- }
146
-
147
166
private static void processBlock (HIRBlock block , ScheduleResult schedule ) {
148
167
DebugContext debug = block .getBeginNode ().getDebug ();
149
168
new LowerGuards (debug .isDumpEnabledForMethod () || debug .isLogEnabledForMethod (), schedule ).processNodes (block );
0 commit comments