< prev index next >

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

Print this page




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  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 jdk.vm.ci.meta.MetaAccessProvider;
  34 import jdk.vm.ci.meta.ResolvedJavaType;
  35 import org.graalvm.compiler.core.common.calc.Condition;
  36 import org.graalvm.compiler.core.common.type.IntegerStamp;
  37 import org.graalvm.compiler.core.common.type.Stamp;
  38 import org.graalvm.compiler.core.common.type.StampFactory;
  39 import org.graalvm.compiler.debug.CounterKey;
  40 import org.graalvm.compiler.debug.DebugContext;
  41 import org.graalvm.compiler.debug.GraalError;
  42 import org.graalvm.compiler.graph.Node;
  43 import org.graalvm.compiler.graph.NodeClass;
  44 import org.graalvm.compiler.graph.iterators.NodeIterable;
  45 import org.graalvm.compiler.graph.spi.Canonicalizable;


  57 import org.graalvm.compiler.nodes.calc.ObjectEqualsNode;
  58 import org.graalvm.compiler.nodes.extended.UnboxNode;
  59 import org.graalvm.compiler.nodes.java.InstanceOfNode;
  60 import org.graalvm.compiler.nodes.java.LoadFieldNode;
  61 import org.graalvm.compiler.nodes.spi.LIRLowerable;
  62 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
  63 import org.graalvm.compiler.nodes.util.GraphUtil;
  64 import org.graalvm.util.EconomicMap;
  65 import org.graalvm.util.Equivalence;
  66 
  67 import jdk.vm.ci.meta.Constant;
  68 import jdk.vm.ci.meta.ConstantReflectionProvider;
  69 import jdk.vm.ci.meta.JavaConstant;
  70 import jdk.vm.ci.meta.JavaKind;
  71 import jdk.vm.ci.meta.PrimitiveConstant;
  72 
  73 /**
  74  * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome
  75  * of a comparison.
  76  */
  77 @NodeInfo(cycles = CYCLES_2, size = SIZE_2, sizeRationale = "2 jmps")
  78 public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable {
  79     public static final NodeClass<IfNode> TYPE = NodeClass.create(IfNode.class);
  80 
  81     private static final CounterKey CORRECTED_PROBABILITIES = DebugContext.counter("CorrectedProbabilities");
  82 
  83     @Successor AbstractBeginNode trueSuccessor;
  84     @Successor AbstractBeginNode falseSuccessor;
  85     @Input(InputType.Condition) LogicNode condition;
  86     protected double trueSuccessorProbability;
  87 
  88     public LogicNode condition() {
  89         return condition;
  90     }
  91 
  92     public void setCondition(LogicNode x) {
  93         updateUsages(condition, x);
  94         condition = x;
  95     }
  96 
  97     public IfNode(LogicNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double trueSuccessorProbability) {


 358                     return false;
 359                 }
 360             }
 361             if (!(node instanceof FixedGuardNode)) {
 362                 continue;
 363             }
 364             FixedGuardNode fixed = (FixedGuardNode) node;
 365             if (!(fixed.condition() instanceof IntegerEqualsNode)) {
 366                 continue;
 367             }
 368             IntegerEqualsNode equals = (IntegerEqualsNode) fixed.condition();
 369             if ((isUnboxedFrom(meta, equals.getX(), x) && isUnboxedFrom(meta, equals.getY(), y)) || (isUnboxedFrom(meta, equals.getX(), y) && isUnboxedFrom(meta, equals.getY(), x))) {
 370                 unboxCheck = fixed;
 371             }
 372         }
 373         if (unbox == null || unboxCheck == null) {
 374             return false;
 375         }
 376 
 377         // Falsify the reference check.
 378         setCondition(graph().addOrUnique(LogicConstantNode.contradiction()));
 379 
 380         return true;
 381     }
 382 
 383     /**
 384      * Try to optimize this as if it were a {@link ConditionalNode}.
 385      */
 386     private boolean conditionalNodeOptimization(SimplifierTool tool) {
 387         if (trueSuccessor().next() instanceof AbstractEndNode && falseSuccessor().next() instanceof AbstractEndNode) {
 388             AbstractEndNode trueEnd = (AbstractEndNode) trueSuccessor().next();
 389             AbstractEndNode falseEnd = (AbstractEndNode) falseSuccessor().next();
 390             if (trueEnd.merge() != falseEnd.merge()) {
 391                 return false;
 392             }
 393             if (!(trueEnd.merge() instanceof MergeNode)) {
 394                 return false;
 395             }
 396             MergeNode merge = (MergeNode) trueEnd.merge();
 397             if (merge.usages().count() != 1 || merge.phis().count() != 1) {
 398                 return false;


 709             if (trueValue != null) {
 710                 if (trueValue == falseValue) {
 711                     value = trueValue;
 712                 } else {
 713                     value = canonicalizeConditionalCascade(trueValue, falseValue);
 714                     if (value == null) {
 715                         return false;
 716                     }
 717                 }
 718             }
 719             ReturnNode newReturn = graph().add(new ReturnNode(value));
 720             replaceAtPredecessor(newReturn);
 721             GraphUtil.killCFG(this);
 722             return true;
 723         }
 724         return false;
 725     }
 726 
 727     protected void removeThroughFalseBranch(SimplifierTool tool, AbstractMergeNode merge) {
 728         AbstractBeginNode trueBegin = trueSuccessor();

 729         graph().removeSplitPropagate(this, trueBegin);
 730         tool.addToWorkList(trueBegin);
 731         if (condition() != null) {
 732             GraphUtil.tryKillUnused(condition());
 733         }
 734         if (merge.isAlive() && merge.forwardEndCount() > 1) {
 735             for (FixedNode end : merge.forwardEnds()) {
 736                 Node cur = end;
 737                 while (cur != null && cur.predecessor() instanceof BeginNode) {
 738                     cur = cur.predecessor();
 739                 }
 740                 if (cur != null && cur.predecessor() instanceof IfNode) {
 741                     tool.addToWorkList(cur.predecessor());
 742                 }
 743             }
 744         }
 745     }
 746 
 747     private ValueNode canonicalizeConditionalCascade(ValueNode trueValue, ValueNode falseValue) {
 748         if (trueValue.getStackKind() != falseValue.getStackKind()) {
 749             return null;
 750         }
 751         if (trueValue.getStackKind() != JavaKind.Int && trueValue.getStackKind() != JavaKind.Long) {
 752             return null;




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  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_1;
  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 jdk.vm.ci.meta.MetaAccessProvider;
  34 import jdk.vm.ci.meta.ResolvedJavaType;
  35 import org.graalvm.compiler.core.common.calc.Condition;
  36 import org.graalvm.compiler.core.common.type.IntegerStamp;
  37 import org.graalvm.compiler.core.common.type.Stamp;
  38 import org.graalvm.compiler.core.common.type.StampFactory;
  39 import org.graalvm.compiler.debug.CounterKey;
  40 import org.graalvm.compiler.debug.DebugContext;
  41 import org.graalvm.compiler.debug.GraalError;
  42 import org.graalvm.compiler.graph.Node;
  43 import org.graalvm.compiler.graph.NodeClass;
  44 import org.graalvm.compiler.graph.iterators.NodeIterable;
  45 import org.graalvm.compiler.graph.spi.Canonicalizable;


  57 import org.graalvm.compiler.nodes.calc.ObjectEqualsNode;
  58 import org.graalvm.compiler.nodes.extended.UnboxNode;
  59 import org.graalvm.compiler.nodes.java.InstanceOfNode;
  60 import org.graalvm.compiler.nodes.java.LoadFieldNode;
  61 import org.graalvm.compiler.nodes.spi.LIRLowerable;
  62 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
  63 import org.graalvm.compiler.nodes.util.GraphUtil;
  64 import org.graalvm.util.EconomicMap;
  65 import org.graalvm.util.Equivalence;
  66 
  67 import jdk.vm.ci.meta.Constant;
  68 import jdk.vm.ci.meta.ConstantReflectionProvider;
  69 import jdk.vm.ci.meta.JavaConstant;
  70 import jdk.vm.ci.meta.JavaKind;
  71 import jdk.vm.ci.meta.PrimitiveConstant;
  72 
  73 /**
  74  * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome
  75  * of a comparison.
  76  */
  77 @NodeInfo(cycles = CYCLES_1, size = SIZE_2, sizeRationale = "2 jmps")
  78 public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable {
  79     public static final NodeClass<IfNode> TYPE = NodeClass.create(IfNode.class);
  80 
  81     private static final CounterKey CORRECTED_PROBABILITIES = DebugContext.counter("CorrectedProbabilities");
  82 
  83     @Successor AbstractBeginNode trueSuccessor;
  84     @Successor AbstractBeginNode falseSuccessor;
  85     @Input(InputType.Condition) LogicNode condition;
  86     protected double trueSuccessorProbability;
  87 
  88     public LogicNode condition() {
  89         return condition;
  90     }
  91 
  92     public void setCondition(LogicNode x) {
  93         updateUsages(condition, x);
  94         condition = x;
  95     }
  96 
  97     public IfNode(LogicNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double trueSuccessorProbability) {


 358                     return false;
 359                 }
 360             }
 361             if (!(node instanceof FixedGuardNode)) {
 362                 continue;
 363             }
 364             FixedGuardNode fixed = (FixedGuardNode) node;
 365             if (!(fixed.condition() instanceof IntegerEqualsNode)) {
 366                 continue;
 367             }
 368             IntegerEqualsNode equals = (IntegerEqualsNode) fixed.condition();
 369             if ((isUnboxedFrom(meta, equals.getX(), x) && isUnboxedFrom(meta, equals.getY(), y)) || (isUnboxedFrom(meta, equals.getX(), y) && isUnboxedFrom(meta, equals.getY(), x))) {
 370                 unboxCheck = fixed;
 371             }
 372         }
 373         if (unbox == null || unboxCheck == null) {
 374             return false;
 375         }
 376 
 377         // Falsify the reference check.
 378         setCondition(graph().addOrUniqueWithInputs(LogicConstantNode.contradiction()));
 379 
 380         return true;
 381     }
 382 
 383     /**
 384      * Try to optimize this as if it were a {@link ConditionalNode}.
 385      */
 386     private boolean conditionalNodeOptimization(SimplifierTool tool) {
 387         if (trueSuccessor().next() instanceof AbstractEndNode && falseSuccessor().next() instanceof AbstractEndNode) {
 388             AbstractEndNode trueEnd = (AbstractEndNode) trueSuccessor().next();
 389             AbstractEndNode falseEnd = (AbstractEndNode) falseSuccessor().next();
 390             if (trueEnd.merge() != falseEnd.merge()) {
 391                 return false;
 392             }
 393             if (!(trueEnd.merge() instanceof MergeNode)) {
 394                 return false;
 395             }
 396             MergeNode merge = (MergeNode) trueEnd.merge();
 397             if (merge.usages().count() != 1 || merge.phis().count() != 1) {
 398                 return false;


 709             if (trueValue != null) {
 710                 if (trueValue == falseValue) {
 711                     value = trueValue;
 712                 } else {
 713                     value = canonicalizeConditionalCascade(trueValue, falseValue);
 714                     if (value == null) {
 715                         return false;
 716                     }
 717                 }
 718             }
 719             ReturnNode newReturn = graph().add(new ReturnNode(value));
 720             replaceAtPredecessor(newReturn);
 721             GraphUtil.killCFG(this);
 722             return true;
 723         }
 724         return false;
 725     }
 726 
 727     protected void removeThroughFalseBranch(SimplifierTool tool, AbstractMergeNode merge) {
 728         AbstractBeginNode trueBegin = trueSuccessor();
 729         LogicNode conditionNode = condition();
 730         graph().removeSplitPropagate(this, trueBegin);
 731         tool.addToWorkList(trueBegin);
 732         if (conditionNode != null) {
 733             GraphUtil.tryKillUnused(conditionNode);
 734         }
 735         if (merge.isAlive() && merge.forwardEndCount() > 1) {
 736             for (FixedNode end : merge.forwardEnds()) {
 737                 Node cur = end;
 738                 while (cur != null && cur.predecessor() instanceof BeginNode) {
 739                     cur = cur.predecessor();
 740                 }
 741                 if (cur != null && cur.predecessor() instanceof IfNode) {
 742                     tool.addToWorkList(cur.predecessor());
 743                 }
 744             }
 745         }
 746     }
 747 
 748     private ValueNode canonicalizeConditionalCascade(ValueNode trueValue, ValueNode falseValue) {
 749         if (trueValue.getStackKind() != falseValue.getStackKind()) {
 750             return null;
 751         }
 752         if (trueValue.getStackKind() != JavaKind.Int && trueValue.getStackKind() != JavaKind.Long) {
 753             return null;


< prev index next >