11/*
2- * Copyright (c) 2011, 2023 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2011, 2024 , 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
5555import jdk .graal .compiler .nodes .DeoptimizeNode ;
5656import jdk .graal .compiler .nodes .FixedNode ;
5757import jdk .graal .compiler .nodes .FixedWithNextNode ;
58+ import jdk .graal .compiler .nodes .GraphState ;
5859import jdk .graal .compiler .nodes .LoopBeginNode ;
5960import jdk .graal .compiler .nodes .LoopEndNode ;
6061import jdk .graal .compiler .nodes .LoopExitNode ;
@@ -333,6 +334,14 @@ private static ControlFlowGraph lookupCached(StructuredGraph graph, boolean modi
333334 return lastCFG ;
334335 }
335336 }
337+ if (graph .getLastSchedule () != null && !graph .isAfterStage (GraphState .StageFlag .FINAL_SCHEDULE )) {
338+ /*
339+ * There is no up to date CFG. If there is a current schedule, its CFG must also be out
340+ * of date. So invalidate the schedule. The only exception is during cleanup phases
341+ * after final scheduling, where we don't want to destroy that schedule.
342+ */
343+ graph .clearLastSchedule ();
344+ }
336345 return null ;
337346 }
338347
@@ -398,7 +407,7 @@ public EconomicMap<LoopBeginNode, LoopFrequencyData> getLocalLoopFrequencyData()
398407 * will return the updated value. This is useful for phases to record temporary effects of
399408 * transformations on loop frequencies, without having to recompute a CFG.
400409 * </p>
401- *
410+ * <p>
402411 * The updated frequency is a cached value local to this CFG. It is <em>not</em> persisted in
403412 * the IR graph. Newly computed {@link ControlFlowGraph} instances will recompute a frequency
404413 * from loop exit probabilities, they will not see this locally cached value. Persistent changes
@@ -688,7 +697,7 @@ private boolean verifyRPOInnerLoopsFirst() {
688697 * it is not an endless loop) {@link LoopExitNode}. For every path exiting a loop a
689698 * {@link LoopExitNode} is required. There is one exception to that rule:
690699 * {@link DeoptimizeNode}.
691- *
700+ * <p>
692701 * Graal does not mandate that a {@link DeoptimizeNode} is preceded by a {@link LoopExitNode}.
693702 * In the following example
694703 *
@@ -699,7 +708,7 @@ private boolean verifyRPOInnerLoopsFirst() {
699708 * }
700709 * }
701710 * </pre>
702- *
711+ * <p>
703712 * the IR does not have a preceding loop exit node before the deopt node. However, for regular
704713 * control flow sinks (returns, throws, etc) like in the following example
705714 *
@@ -710,9 +719,9 @@ private boolean verifyRPOInnerLoopsFirst() {
710719 * }
711720 * }
712721 * </pre>
713- *
722+ * <p>
714723 * Graal IR creates a {@link LoopExitNode} before the {@link ReturnNode}.
715- *
724+ * <p>
716725 * Because of the "imprecision" in the definition a regular basic block exiting a loop and a
717726 * "dominator tree" loop exit are not necessarily the same. If a path after a control flow split
718727 * unconditionally flows into a deopt it is a "dominator loop exit" while a regular loop exit
@@ -810,9 +819,9 @@ private boolean rpoInnerLoopsFirst(Consumer<HIRBlock> perBasicBlockOption, Consu
810819 /**
811820 * Determine if sequential predecessor blocks of this block in a not-fully-canonicalized graph
812821 * exit a loop.
813- *
822+ * <p>
814823 * Example: Sequential basic block: loop exit -> invoke -> killing begin -> loopend/exit
815- *
824+ * <p>
816825 * These cases cause problems in the {@link #verifyRPOInnerLoopsFirst()} loop verification of
817826 * inner loop blocks because the granularity of loop ends and exits are not on block boundaries:
818827 * a loop exit block can also be a loop end to an outer loop, which makes verification that the
0 commit comments