From c193592d911e4b23b962390150c0a628961f09a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C3=B6=20Barany?= Date: Tue, 14 Jan 2025 15:18:08 +0100 Subject: [PATCH] ConvertDeoptimizeToGuard: Add new guard before killing CFG paths --- .../phases/ConvertDeoptimizeToGuardPhase.java | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/ConvertDeoptimizeToGuardPhase.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/ConvertDeoptimizeToGuardPhase.java index b12794a0112c..a284a48d5e0e 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/ConvertDeoptimizeToGuardPhase.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/ConvertDeoptimizeToGuardPhase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -243,8 +243,30 @@ public static void propagateFixed(FixedNode from, StaticDeoptimizingNode deopt, FixedGuardNode guard = graph.add( new FixedGuardNode(conditionNode, deopt.getReason(), deopt.getAction(), deopt.getSpeculation(), negateGuardCondition, survivingSuccessorPosition)); FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor(); - AbstractBeginNode survivingSuccessor; + /** + * We may have the following special case if pred is a LoopBegin: + * + *
+                             *     LoopBegin (= pred) <--------+
+                             *         |                       |
+                             *         | <- guard insert pos   |
+                             *         |                       |
+                             *       ifNode                    |
+                             *       |     \                   |
+                             *  surviving   LoopEnd -----------+
+                             *       |
+                             *      ...
+                             * 
+ * + * If the only loop end is on the non-surviving successor path, then + * killing that CFG path will also kill the LoopBegin, i.e., the pred + * node. We would lose our place in the graph for inserting the guard. + * Therefore, insert the guard before killing anything. + */ + pred.setNext(guard); + guard.setNext(ifNode); + AbstractBeginNode survivingSuccessor; if (negateGuardCondition) { survivingSuccessor = ifNode.falseSuccessor(); } else { @@ -265,9 +287,6 @@ public static void propagateFixed(FixedNode from, StaticDeoptimizingNode deopt, survivingSuccessor.replaceAtUsages(newGuard, InputType.Guard); } graph.getOptimizationLog().report(ConvertDeoptimizeToGuardPhase.class, "DeoptimizeToGuardConversion", deopt.asNode()); - FixedNode next = pred.next(); - pred.setNext(guard); - guard.setNext(next); assert providers != null; SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(providers, false, graph.getAssumptions(), graph.getOptions()); if (survivingSuccessor.isAlive()) {