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 hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes

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

Print this page




  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.nodes;
  24 
  25 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
  26 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Arrays;
  30 import java.util.Iterator;
  31 import java.util.List;
  32 
  33 import org.graalvm.compiler.core.common.calc.Condition;
  34 import org.graalvm.compiler.core.common.type.IntegerStamp;
  35 import org.graalvm.compiler.core.common.type.Stamp;
  36 import org.graalvm.compiler.core.common.type.StampFactory;
  37 import org.graalvm.compiler.debug.Debug;
  38 import org.graalvm.compiler.debug.DebugCounter;
  39 import org.graalvm.compiler.debug.GraalError;
  40 import org.graalvm.compiler.graph.Node;
  41 import org.graalvm.compiler.graph.NodeClass;
  42 import org.graalvm.compiler.graph.iterators.NodeIterable;
  43 import org.graalvm.compiler.graph.spi.Canonicalizable;
  44 import org.graalvm.compiler.graph.spi.Simplifiable;
  45 import org.graalvm.compiler.graph.spi.SimplifierTool;
  46 import org.graalvm.compiler.nodeinfo.InputType;
  47 import org.graalvm.compiler.nodeinfo.NodeInfo;
  48 import org.graalvm.compiler.nodes.calc.CompareNode;
  49 import org.graalvm.compiler.nodes.calc.ConditionalNode;
  50 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
  51 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
  52 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
  53 import org.graalvm.compiler.nodes.calc.IsNullNode;
  54 import org.graalvm.compiler.nodes.calc.NormalizeCompareNode;
  55 import org.graalvm.compiler.nodes.java.InstanceOfNode;
  56 import org.graalvm.compiler.nodes.spi.LIRLowerable;
  57 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
  58 import org.graalvm.compiler.nodes.util.GraphUtil;
  59 import org.graalvm.util.EconomicMap;
  60 import org.graalvm.util.Equivalence;
  61 
  62 import jdk.vm.ci.meta.Constant;
  63 import jdk.vm.ci.meta.ConstantReflectionProvider;
  64 import jdk.vm.ci.meta.JavaConstant;
  65 import jdk.vm.ci.meta.JavaKind;
  66 import jdk.vm.ci.meta.PrimitiveConstant;
  67 
  68 /**
  69  * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome
  70  * of a comparison.
  71  */
  72 @NodeInfo(cycles = CYCLES_2, size = SIZE_2, sizeRationale = "2 jmps")
  73 public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable {
  74     public static final NodeClass<IfNode> TYPE = NodeClass.create(IfNode.class);
  75 
  76     private static final DebugCounter CORRECTED_PROBABILITIES = Debug.counter("CorrectedProbabilities");
  77 
  78     @Successor AbstractBeginNode trueSuccessor;
  79     @Successor AbstractBeginNode falseSuccessor;
  80     @Input(InputType.Condition) LogicNode condition;
  81     protected double trueSuccessorProbability;
  82 
  83     public LogicNode condition() {
  84         return condition;
  85     }
  86 
  87     public void setCondition(LogicNode x) {
  88         updateUsages(condition, x);
  89         condition = x;
  90     }
  91 
  92     public IfNode(LogicNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double trueSuccessorProbability) {
  93         this(condition, BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor), trueSuccessorProbability);
  94     }
  95 
  96     public IfNode(LogicNode condition, AbstractBeginNode trueSuccessor, AbstractBeginNode falseSuccessor, double trueSuccessorProbability) {


 162     public boolean verify() {
 163         assertTrue(condition() != null, "missing condition");
 164         assertTrue(trueSuccessor() != null, "missing trueSuccessor");
 165         assertTrue(falseSuccessor() != null, "missing falseSuccessor");
 166         return super.verify();
 167     }
 168 
 169     public void eliminateNegation() {
 170         AbstractBeginNode oldTrueSuccessor = trueSuccessor;
 171         AbstractBeginNode oldFalseSuccessor = falseSuccessor;
 172         trueSuccessor = oldFalseSuccessor;
 173         falseSuccessor = oldTrueSuccessor;
 174         trueSuccessorProbability = 1 - trueSuccessorProbability;
 175         setCondition(((LogicNegationNode) condition).getValue());
 176     }
 177 
 178     @Override
 179     public void simplify(SimplifierTool tool) {
 180         if (trueSuccessor().next() instanceof DeoptimizeNode) {
 181             if (trueSuccessorProbability != 0) {
 182                 CORRECTED_PROBABILITIES.increment();
 183                 trueSuccessorProbability = 0;
 184             }
 185         } else if (falseSuccessor().next() instanceof DeoptimizeNode) {
 186             if (trueSuccessorProbability != 1) {
 187                 CORRECTED_PROBABILITIES.increment();
 188                 trueSuccessorProbability = 1;
 189             }
 190         }
 191 
 192         if (condition() instanceof LogicNegationNode) {
 193             eliminateNegation();
 194         }
 195         if (condition() instanceof LogicConstantNode) {
 196             LogicConstantNode c = (LogicConstantNode) condition();
 197             if (c.getValue()) {
 198                 tool.deleteBranch(falseSuccessor());
 199                 tool.addToWorkList(trueSuccessor());
 200                 graph().removeSplit(this, trueSuccessor());
 201             } else {
 202                 tool.deleteBranch(trueSuccessor());
 203                 tool.addToWorkList(falseSuccessor());
 204                 graph().removeSplit(this, falseSuccessor());
 205             }
 206             return;
 207         }


 436             }
 437         } else if (next1 instanceof LoopExitNode && next2 instanceof LoopExitNode) {
 438             LoopExitNode exit1 = (LoopExitNode) next1;
 439             LoopExitNode exit2 = (LoopExitNode) next2;
 440             if (exit1.loopBegin() == exit2.loopBegin() && exit1.stateAfter() == exit2.stateAfter() && exit1.stateAfter() == null && sameDestination(exit1, exit2)) {
 441                 // Exit the same loop and end up at the same place.
 442                 return true;
 443             }
 444         } else if (next1 instanceof ReturnNode && next2 instanceof ReturnNode) {
 445             ReturnNode exit1 = (ReturnNode) next1;
 446             ReturnNode exit2 = (ReturnNode) next2;
 447             if (exit1.result() == exit2.result()) {
 448                 // Exit the same loop and end up at the same place.
 449                 return true;
 450             }
 451         }
 452         return false;
 453     }
 454 
 455     private static boolean prepareForSwap(ConstantReflectionProvider constantReflection, LogicNode a, LogicNode b) {

 456         if (a instanceof InstanceOfNode) {
 457             InstanceOfNode instanceOfA = (InstanceOfNode) a;
 458             if (b instanceof IsNullNode) {
 459                 IsNullNode isNullNode = (IsNullNode) b;
 460                 if (isNullNode.getValue() == instanceOfA.getValue()) {
 461                     Debug.log("Can swap instanceof and isnull if");
 462                     return true;
 463                 }
 464             } else if (b instanceof InstanceOfNode) {
 465                 InstanceOfNode instanceOfB = (InstanceOfNode) b;
 466                 if (instanceOfA.getValue() == instanceOfB.getValue() && !instanceOfA.type().getType().isInterface() && !instanceOfB.type().getType().isInterface() &&
 467                                 !instanceOfA.type().getType().isAssignableFrom(instanceOfB.type().getType()) && !instanceOfB.type().getType().isAssignableFrom(instanceOfA.type().getType())) {
 468                     // Two instanceof on the same value with mutually exclusive types.
 469                     Debug.log("Can swap instanceof for types %s and %s", instanceOfA.type(), instanceOfB.type());
 470                     return true;
 471                 }
 472             }
 473         } else if (a instanceof CompareNode) {
 474             CompareNode compareA = (CompareNode) a;
 475             Condition conditionA = compareA.condition();
 476             if (compareA.unorderedIsTrue()) {
 477                 return false;
 478             }
 479             if (b instanceof CompareNode) {
 480                 CompareNode compareB = (CompareNode) b;
 481                 if (compareA == compareB) {
 482                     Debug.log("Same conditions => do not swap and leave the work for global value numbering.");
 483                     return false;
 484                 }
 485                 if (compareB.unorderedIsTrue()) {
 486                     return false;
 487                 }
 488                 Condition comparableCondition = null;
 489                 Condition conditionB = compareB.condition();
 490                 if (compareB.getX() == compareA.getX() && compareB.getY() == compareA.getY()) {
 491                     comparableCondition = conditionB;
 492                 } else if (compareB.getX() == compareA.getY() && compareB.getY() == compareA.getX()) {
 493                     comparableCondition = conditionB.mirror();
 494                 }
 495 
 496                 if (comparableCondition != null) {
 497                     Condition combined = conditionA.join(comparableCondition);
 498                     if (combined == null) {
 499                         // The two conditions are disjoint => can reorder.
 500                         Debug.log("Can swap disjoint coditions on same values: %s and %s", conditionA, comparableCondition);
 501                         return true;
 502                     }
 503                 } else if (conditionA == Condition.EQ && conditionB == Condition.EQ) {
 504                     boolean canSwap = false;
 505                     if ((compareA.getX() == compareB.getX() && valuesDistinct(constantReflection, compareA.getY(), compareB.getY()))) {
 506                         canSwap = true;
 507                     } else if ((compareA.getX() == compareB.getY() && valuesDistinct(constantReflection, compareA.getY(), compareB.getX()))) {
 508                         canSwap = true;
 509                     } else if ((compareA.getY() == compareB.getX() && valuesDistinct(constantReflection, compareA.getX(), compareB.getY()))) {
 510                         canSwap = true;
 511                     } else if ((compareA.getY() == compareB.getY() && valuesDistinct(constantReflection, compareA.getX(), compareB.getX()))) {
 512                         canSwap = true;
 513                     }
 514 
 515                     if (canSwap) {
 516                         Debug.log("Can swap equality condition with one shared and one disjoint value.");
 517                         return true;
 518                     }
 519                 }
 520             }
 521         }
 522 
 523         return false;
 524     }
 525 
 526     private static boolean valuesDistinct(ConstantReflectionProvider constantReflection, ValueNode a, ValueNode b) {
 527         if (a.isConstant() && b.isConstant()) {
 528             Boolean equal = constantReflection.constantEquals(a.asConstant(), b.asConstant());
 529             if (equal != null) {
 530                 return !equal.booleanValue();
 531             }
 532         }
 533 
 534         Stamp stampA = a.stamp();
 535         Stamp stampB = b.stamp();
 536         return stampA.alwaysDistinct(stampB);




  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.nodes;
  24 
  25 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
  26 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Arrays;
  30 import java.util.Iterator;
  31 import java.util.List;
  32 
  33 import org.graalvm.compiler.core.common.calc.Condition;
  34 import org.graalvm.compiler.core.common.type.IntegerStamp;
  35 import org.graalvm.compiler.core.common.type.Stamp;
  36 import org.graalvm.compiler.core.common.type.StampFactory;
  37 import org.graalvm.compiler.debug.CounterKey;
  38 import org.graalvm.compiler.debug.DebugContext;
  39 import org.graalvm.compiler.debug.GraalError;
  40 import org.graalvm.compiler.graph.Node;
  41 import org.graalvm.compiler.graph.NodeClass;
  42 import org.graalvm.compiler.graph.iterators.NodeIterable;
  43 import org.graalvm.compiler.graph.spi.Canonicalizable;
  44 import org.graalvm.compiler.graph.spi.Simplifiable;
  45 import org.graalvm.compiler.graph.spi.SimplifierTool;
  46 import org.graalvm.compiler.nodeinfo.InputType;
  47 import org.graalvm.compiler.nodeinfo.NodeInfo;
  48 import org.graalvm.compiler.nodes.calc.CompareNode;
  49 import org.graalvm.compiler.nodes.calc.ConditionalNode;
  50 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
  51 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
  52 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
  53 import org.graalvm.compiler.nodes.calc.IsNullNode;
  54 import org.graalvm.compiler.nodes.calc.NormalizeCompareNode;
  55 import org.graalvm.compiler.nodes.java.InstanceOfNode;
  56 import org.graalvm.compiler.nodes.spi.LIRLowerable;
  57 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
  58 import org.graalvm.compiler.nodes.util.GraphUtil;
  59 import org.graalvm.util.EconomicMap;
  60 import org.graalvm.util.Equivalence;
  61 
  62 import jdk.vm.ci.meta.Constant;
  63 import jdk.vm.ci.meta.ConstantReflectionProvider;
  64 import jdk.vm.ci.meta.JavaConstant;
  65 import jdk.vm.ci.meta.JavaKind;
  66 import jdk.vm.ci.meta.PrimitiveConstant;
  67 
  68 /**
  69  * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome
  70  * of a comparison.
  71  */
  72 @NodeInfo(cycles = CYCLES_2, size = SIZE_2, sizeRationale = "2 jmps")
  73 public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable {
  74     public static final NodeClass<IfNode> TYPE = NodeClass.create(IfNode.class);
  75 
  76     private static final CounterKey CORRECTED_PROBABILITIES = DebugContext.counter("CorrectedProbabilities");
  77 
  78     @Successor AbstractBeginNode trueSuccessor;
  79     @Successor AbstractBeginNode falseSuccessor;
  80     @Input(InputType.Condition) LogicNode condition;
  81     protected double trueSuccessorProbability;
  82 
  83     public LogicNode condition() {
  84         return condition;
  85     }
  86 
  87     public void setCondition(LogicNode x) {
  88         updateUsages(condition, x);
  89         condition = x;
  90     }
  91 
  92     public IfNode(LogicNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double trueSuccessorProbability) {
  93         this(condition, BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor), trueSuccessorProbability);
  94     }
  95 
  96     public IfNode(LogicNode condition, AbstractBeginNode trueSuccessor, AbstractBeginNode falseSuccessor, double trueSuccessorProbability) {


 162     public boolean verify() {
 163         assertTrue(condition() != null, "missing condition");
 164         assertTrue(trueSuccessor() != null, "missing trueSuccessor");
 165         assertTrue(falseSuccessor() != null, "missing falseSuccessor");
 166         return super.verify();
 167     }
 168 
 169     public void eliminateNegation() {
 170         AbstractBeginNode oldTrueSuccessor = trueSuccessor;
 171         AbstractBeginNode oldFalseSuccessor = falseSuccessor;
 172         trueSuccessor = oldFalseSuccessor;
 173         falseSuccessor = oldTrueSuccessor;
 174         trueSuccessorProbability = 1 - trueSuccessorProbability;
 175         setCondition(((LogicNegationNode) condition).getValue());
 176     }
 177 
 178     @Override
 179     public void simplify(SimplifierTool tool) {
 180         if (trueSuccessor().next() instanceof DeoptimizeNode) {
 181             if (trueSuccessorProbability != 0) {
 182                 CORRECTED_PROBABILITIES.increment(getDebug());
 183                 trueSuccessorProbability = 0;
 184             }
 185         } else if (falseSuccessor().next() instanceof DeoptimizeNode) {
 186             if (trueSuccessorProbability != 1) {
 187                 CORRECTED_PROBABILITIES.increment(getDebug());
 188                 trueSuccessorProbability = 1;
 189             }
 190         }
 191 
 192         if (condition() instanceof LogicNegationNode) {
 193             eliminateNegation();
 194         }
 195         if (condition() instanceof LogicConstantNode) {
 196             LogicConstantNode c = (LogicConstantNode) condition();
 197             if (c.getValue()) {
 198                 tool.deleteBranch(falseSuccessor());
 199                 tool.addToWorkList(trueSuccessor());
 200                 graph().removeSplit(this, trueSuccessor());
 201             } else {
 202                 tool.deleteBranch(trueSuccessor());
 203                 tool.addToWorkList(falseSuccessor());
 204                 graph().removeSplit(this, falseSuccessor());
 205             }
 206             return;
 207         }


 436             }
 437         } else if (next1 instanceof LoopExitNode && next2 instanceof LoopExitNode) {
 438             LoopExitNode exit1 = (LoopExitNode) next1;
 439             LoopExitNode exit2 = (LoopExitNode) next2;
 440             if (exit1.loopBegin() == exit2.loopBegin() && exit1.stateAfter() == exit2.stateAfter() && exit1.stateAfter() == null && sameDestination(exit1, exit2)) {
 441                 // Exit the same loop and end up at the same place.
 442                 return true;
 443             }
 444         } else if (next1 instanceof ReturnNode && next2 instanceof ReturnNode) {
 445             ReturnNode exit1 = (ReturnNode) next1;
 446             ReturnNode exit2 = (ReturnNode) next2;
 447             if (exit1.result() == exit2.result()) {
 448                 // Exit the same loop and end up at the same place.
 449                 return true;
 450             }
 451         }
 452         return false;
 453     }
 454 
 455     private static boolean prepareForSwap(ConstantReflectionProvider constantReflection, LogicNode a, LogicNode b) {
 456         DebugContext debug = a.getDebug();
 457         if (a instanceof InstanceOfNode) {
 458             InstanceOfNode instanceOfA = (InstanceOfNode) a;
 459             if (b instanceof IsNullNode) {
 460                 IsNullNode isNullNode = (IsNullNode) b;
 461                 if (isNullNode.getValue() == instanceOfA.getValue()) {
 462                     debug.log("Can swap instanceof and isnull if");
 463                     return true;
 464                 }
 465             } else if (b instanceof InstanceOfNode) {
 466                 InstanceOfNode instanceOfB = (InstanceOfNode) b;
 467                 if (instanceOfA.getValue() == instanceOfB.getValue() && !instanceOfA.type().getType().isInterface() && !instanceOfB.type().getType().isInterface() &&
 468                                 !instanceOfA.type().getType().isAssignableFrom(instanceOfB.type().getType()) && !instanceOfB.type().getType().isAssignableFrom(instanceOfA.type().getType())) {
 469                     // Two instanceof on the same value with mutually exclusive types.
 470                     debug.log("Can swap instanceof for types %s and %s", instanceOfA.type(), instanceOfB.type());
 471                     return true;
 472                 }
 473             }
 474         } else if (a instanceof CompareNode) {
 475             CompareNode compareA = (CompareNode) a;
 476             Condition conditionA = compareA.condition();
 477             if (compareA.unorderedIsTrue()) {
 478                 return false;
 479             }
 480             if (b instanceof CompareNode) {
 481                 CompareNode compareB = (CompareNode) b;
 482                 if (compareA == compareB) {
 483                     debug.log("Same conditions => do not swap and leave the work for global value numbering.");
 484                     return false;
 485                 }
 486                 if (compareB.unorderedIsTrue()) {
 487                     return false;
 488                 }
 489                 Condition comparableCondition = null;
 490                 Condition conditionB = compareB.condition();
 491                 if (compareB.getX() == compareA.getX() && compareB.getY() == compareA.getY()) {
 492                     comparableCondition = conditionB;
 493                 } else if (compareB.getX() == compareA.getY() && compareB.getY() == compareA.getX()) {
 494                     comparableCondition = conditionB.mirror();
 495                 }
 496 
 497                 if (comparableCondition != null) {
 498                     Condition combined = conditionA.join(comparableCondition);
 499                     if (combined == null) {
 500                         // The two conditions are disjoint => can reorder.
 501                         debug.log("Can swap disjoint coditions on same values: %s and %s", conditionA, comparableCondition);
 502                         return true;
 503                     }
 504                 } else if (conditionA == Condition.EQ && conditionB == Condition.EQ) {
 505                     boolean canSwap = false;
 506                     if ((compareA.getX() == compareB.getX() && valuesDistinct(constantReflection, compareA.getY(), compareB.getY()))) {
 507                         canSwap = true;
 508                     } else if ((compareA.getX() == compareB.getY() && valuesDistinct(constantReflection, compareA.getY(), compareB.getX()))) {
 509                         canSwap = true;
 510                     } else if ((compareA.getY() == compareB.getX() && valuesDistinct(constantReflection, compareA.getX(), compareB.getY()))) {
 511                         canSwap = true;
 512                     } else if ((compareA.getY() == compareB.getY() && valuesDistinct(constantReflection, compareA.getX(), compareB.getX()))) {
 513                         canSwap = true;
 514                     }
 515 
 516                     if (canSwap) {
 517                         debug.log("Can swap equality condition with one shared and one disjoint value.");
 518                         return true;
 519                     }
 520                 }
 521             }
 522         }
 523 
 524         return false;
 525     }
 526 
 527     private static boolean valuesDistinct(ConstantReflectionProvider constantReflection, ValueNode a, ValueNode b) {
 528         if (a.isConstant() && b.isConstant()) {
 529             Boolean equal = constantReflection.constantEquals(a.asConstant(), b.asConstant());
 530             if (equal != null) {
 531                 return !equal.booleanValue();
 532             }
 533         }
 534 
 535         Stamp stampA = a.stamp();
 536         Stamp stampB = b.stamp();
 537         return stampA.alwaysDistinct(stampB);


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