src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File open Cdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java

Print this page

        

*** 28,39 **** import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; - import jdk.vm.ci.meta.MetaAccessProvider; - import jdk.vm.ci.meta.ResolvedJavaType; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.debug.CounterKey; --- 28,37 ----
*** 65,75 **** --- 63,75 ---- import org.graalvm.util.Equivalence; import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; + import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.PrimitiveConstant; + import jdk.vm.ci.meta.ResolvedJavaType; /** * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome * of a comparison. */
*** 414,423 **** --- 414,424 ---- * canonicalizeConditional returns possibly new nodes so add them to the graph. */ if (result.graph() == null) { result = graph().addOrUniqueWithInputs(result); } + result = proxyReplacement(result); /* * This optimization can be performed even if multiple values merge at this phi * since the two inputs get simplified into one. */ phi.setValueAt(trueEnd, result);
*** 696,705 **** --- 697,707 ---- } else if (distinct == 1) { ValueNode trueValue = singlePhi.valueAt(trueEnd); ValueNode falseValue = singlePhi.valueAt(falseEnd); ValueNode conditional = canonicalizeConditionalCascade(tool, trueValue, falseValue); if (conditional != null) { + conditional = proxyReplacement(conditional); singlePhi.setValueAt(trueEnd, conditional); removeThroughFalseBranch(tool, merge); return true; } }
*** 727,736 **** --- 729,768 ---- return true; } return false; } + private ValueNode proxyReplacement(ValueNode replacement) { + /* + * Special case: Every empty diamond we collapse to a conditional node can potentially + * contain loop exit nodes on both branches. See the graph below: The two loop exits + * (instanceof begin node) exit the same loop. The resulting phi is defined outside the + * loop, but the resulting conditional node will be inside the loop, so we need to proxy the + * resulting conditional node. Callers of this method ensure that true and false successor + * have no usages, therefore a and b in the graph below can never be proxies themselves. + */ + // @formatter:off + // +--+ + // |If| + // +--+ +-----+ +-----+ + // +----+ +----+ | a | | b | + // |Lex | |Lex | +----^+ +^----+ + // +----+ +----+ | | + // +-------+ +---+ + // | Merge +---------+Phi| + // +-------+ +---+ + // @formatter:on + if (this.graph().hasValueProxies()) { + if (trueSuccessor instanceof LoopExitNode && falseSuccessor instanceof LoopExitNode) { + assert ((LoopExitNode) trueSuccessor).loopBegin() == ((LoopExitNode) falseSuccessor).loopBegin(); + assert trueSuccessor.usages().isEmpty() && falseSuccessor.usages().isEmpty(); + return this.graph().addOrUnique(new ValueProxyNode(replacement, (LoopExitNode) trueSuccessor)); + } + } + return replacement; + } + protected void removeThroughFalseBranch(SimplifierTool tool, AbstractMergeNode merge) { AbstractBeginNode trueBegin = trueSuccessor(); LogicNode conditionNode = condition(); graph().removeSplitPropagate(this, trueBegin); tool.addToWorkList(trueBegin);
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File