diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/inlining/InliningUtil.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/inlining/InliningUtil.java index ac40d0344d0a..a1e726802da1 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/inlining/InliningUtil.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/inlining/InliningUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, 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 @@ -592,7 +592,7 @@ public List processInlineeReturns(List returns) { public static InlineeReturnAction NoReturnAction = new InlineeReturnAction(); @SuppressWarnings("try") - private static ValueNode finishInlining(Invoke invoke, StructuredGraph graph, FixedNode firstNode, List returnNodes, UnwindNode unwindNode, + private static void finishInlining(Invoke invoke, StructuredGraph graph, FixedNode firstNode, List returnNodes, UnwindNode unwindNode, StructuredGraph inlineGraph, InlineeReturnAction inlineeReturnAction, Graph.Mark beforeInlining) { List processedReturns = inlineeReturnAction.processInlineeReturns(returnNodes); @@ -637,21 +637,19 @@ private static ValueNode finishInlining(Invoke invoke, StructuredGraph graph, Fi } } - ValueNode returnValue; if (!processedReturns.isEmpty()) { FixedNode next = invoke.next(); invoke.setNext(null); if (processedReturns.size() == 1) { ReturnNode returnNode = processedReturns.get(0); Pair returnAnchorPair = replaceInvokeAtUsages(invokeNode, returnNode.result(), next, beforeInlining); - returnValue = returnAnchorPair.getLeft(); returnNode.replaceAndDelete(returnAnchorPair.getRight()); } else { MergeNode merge = graph.add(new MergeNode()); merge.setStateAfter(stateAfter); ValueNode mergedReturn = mergeReturns(merge, processedReturns); Pair returnAnchorPair = replaceInvokeAtUsages(invokeNode, mergedReturn, merge, beforeInlining); - returnValue = returnAnchorPair.getLeft(); + ValueNode returnValue = returnAnchorPair.getLeft(); assert returnAnchorPair.getRight() == merge : Assertions.errorMessage(returnAnchorPair.getRight(), merge); if (merge.isPhiAtMerge(mergedReturn)) { fixFrameStates(graph, merge, mergedReturn, returnValue); @@ -659,8 +657,20 @@ private static ValueNode finishInlining(Invoke invoke, StructuredGraph graph, Fi merge.setNext(next); } } else { - returnValue = null; - invokeNode.replaceAtUsages(null); + if (invokeNode.hasUsages()) { + JavaKind returnKind = invoke.getTargetMethod().getSignature().getReturnKind(); + if (returnKind != JavaKind.Void) { + /* + * The target method is declared to return a value but does not have any returns + * because it always deoptimizes. Usages of the invoke will usually be removed + * by the following killCFG call, but in special cases they are already + * disconnected from the control flow and survive until the next + * canonicalization or dead code elimination. Until the usages are removed, they + * need some placeholder value as an input to keep the graph valid. + */ + invokeNode.replaceAtUsages(ConstantNode.defaultForKind(returnKind, graph)); + } + } GraphUtil.killCFG(invoke.next()); } @@ -670,8 +680,6 @@ private static ValueNode finishInlining(Invoke invoke, StructuredGraph graph, Fi graph.maybeMarkUnsafeAccess(inlineGraph); assert inlineGraph.getSpeculationLog() == null || inlineGraph.getSpeculationLog() == graph.getSpeculationLog() : "Only the root graph should have a speculation log"; - - return returnValue; } /**