src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ZeroExtendNode.java
changeset 48861 47f19ff9903c
parent 48190 25cfedf27edc
child 50858 2d3e99a72541
equal deleted inserted replaced
48860:5bce1b7e7800 48861:47f19ff9903c
    22  */
    22  */
    23 package org.graalvm.compiler.nodes.calc;
    23 package org.graalvm.compiler.nodes.calc;
    24 
    24 
    25 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
    25 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
    26 
    26 
    27 import org.graalvm.compiler.core.common.calc.Condition;
    27 import org.graalvm.compiler.core.common.calc.CanonicalCondition;
    28 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
    28 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
    29 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
    29 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
    30 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp.Narrow;
    30 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp.Narrow;
    31 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp.ZeroExtend;
    31 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp.ZeroExtend;
    32 import org.graalvm.compiler.core.common.type.IntegerStamp;
    32 import org.graalvm.compiler.core.common.type.IntegerStamp;
    48 @NodeInfo(cycles = CYCLES_1)
    48 @NodeInfo(cycles = CYCLES_1)
    49 public final class ZeroExtendNode extends IntegerConvertNode<ZeroExtend, Narrow> {
    49 public final class ZeroExtendNode extends IntegerConvertNode<ZeroExtend, Narrow> {
    50 
    50 
    51     public static final NodeClass<ZeroExtendNode> TYPE = NodeClass.create(ZeroExtendNode.class);
    51     public static final NodeClass<ZeroExtendNode> TYPE = NodeClass.create(ZeroExtendNode.class);
    52 
    52 
       
    53     private final boolean inputAlwaysPositive;
       
    54 
    53     public ZeroExtendNode(ValueNode input, int resultBits) {
    55     public ZeroExtendNode(ValueNode input, int resultBits) {
    54         this(input, PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)), resultBits);
    56         this(input, PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)), resultBits, false);
    55         assert 0 < PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) && PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) <= resultBits;
    57         assert 0 < PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) && PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) <= resultBits;
    56     }
    58     }
    57 
    59 
    58     public ZeroExtendNode(ValueNode input, int inputBits, int resultBits) {
    60     public ZeroExtendNode(ValueNode input, int inputBits, int resultBits, boolean inputAlwaysPositive) {
    59         super(TYPE, ArithmeticOpTable::getZeroExtend, ArithmeticOpTable::getNarrow, inputBits, resultBits, input);
    61         super(TYPE, ArithmeticOpTable::getZeroExtend, ArithmeticOpTable::getNarrow, inputBits, resultBits, input);
       
    62         this.inputAlwaysPositive = inputAlwaysPositive;
    60     }
    63     }
    61 
    64 
    62     public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
    65     public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
    63         return create(input, PrimitiveStamp.getBits(input.stamp(view)), resultBits, view);
    66         return create(input, PrimitiveStamp.getBits(input.stamp(view)), resultBits, view, false);
    64     }
    67     }
    65 
    68 
    66     public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view) {
    69     public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view) {
       
    70         return create(input, inputBits, resultBits, view, false);
       
    71     }
       
    72 
       
    73     public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view, boolean alwaysPositive) {
    67         IntegerConvertOp<ZeroExtend> signExtend = ArithmeticOpTable.forStamp(input.stamp(view)).getZeroExtend();
    74         IntegerConvertOp<ZeroExtend> signExtend = ArithmeticOpTable.forStamp(input.stamp(view)).getZeroExtend();
    68         ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp(view)));
    75         ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp(view)));
    69         if (synonym != null) {
    76         if (synonym != null) {
    70             return synonym;
    77             return synonym;
    71         }
    78         }
    72         return canonical(null, input, inputBits, resultBits, view);
    79         return canonical(null, input, inputBits, resultBits, view, alwaysPositive);
    73     }
    80     }
    74 
    81 
    75     @Override
    82     @Override
    76     public boolean isLossless() {
    83     public boolean isLossless() {
    77         return true;
    84         return true;
    78     }
    85     }
    79 
    86 
       
    87     public boolean isInputAlwaysPositive() {
       
    88         return inputAlwaysPositive;
       
    89     }
       
    90 
    80     @Override
    91     @Override
    81     public boolean preservesOrder(Condition cond) {
    92     public boolean preservesOrder(CanonicalCondition cond) {
    82         switch (cond) {
    93         switch (cond) {
    83             case GE:
       
    84             case GT:
       
    85             case LE:
       
    86             case LT:
    94             case LT:
    87                 return false;
    95                 return false;
    88             default:
    96             default:
    89                 return true;
    97                 return true;
    90         }
    98         }
    96         ValueNode ret = super.canonical(tool, forValue);
   104         ValueNode ret = super.canonical(tool, forValue);
    97         if (ret != this) {
   105         if (ret != this) {
    98             return ret;
   106             return ret;
    99         }
   107         }
   100 
   108 
   101         return canonical(this, forValue, getInputBits(), getResultBits(), view);
   109         return canonical(this, forValue, getInputBits(), getResultBits(), view, inputAlwaysPositive);
   102     }
   110     }
   103 
   111 
   104     private static ValueNode canonical(ZeroExtendNode zeroExtendNode, ValueNode forValue, int inputBits, int resultBits, NodeView view) {
   112     private static ValueNode canonical(ZeroExtendNode zeroExtendNode, ValueNode forValue, int inputBits, int resultBits, NodeView view, boolean alwaysPositive) {
   105         ZeroExtendNode self = zeroExtendNode;
   113         ZeroExtendNode self = zeroExtendNode;
   106         if (forValue instanceof ZeroExtendNode) {
   114         if (forValue instanceof ZeroExtendNode) {
   107             // xxxx -(zero-extend)-> 0000 xxxx -(zero-extend)-> 00000000 0000xxxx
   115             // xxxx -(zero-extend)-> 0000 xxxx -(zero-extend)-> 00000000 0000xxxx
   108             // ==> xxxx -(zero-extend)-> 00000000 0000xxxx
   116             // ==> xxxx -(zero-extend)-> 00000000 0000xxxx
   109             ZeroExtendNode other = (ZeroExtendNode) forValue;
   117             ZeroExtendNode other = (ZeroExtendNode) forValue;
   110             return new ZeroExtendNode(other.getValue(), other.getInputBits(), resultBits);
   118             return new ZeroExtendNode(other.getValue(), other.getInputBits(), resultBits, other.isInputAlwaysPositive());
   111         }
   119         }
   112         if (forValue instanceof NarrowNode) {
   120         if (forValue instanceof NarrowNode) {
   113             NarrowNode narrow = (NarrowNode) forValue;
   121             NarrowNode narrow = (NarrowNode) forValue;
   114             Stamp inputStamp = narrow.getValue().stamp(view);
   122             Stamp inputStamp = narrow.getValue().stamp(view);
   115             if (inputStamp instanceof IntegerStamp) {
   123             if (inputStamp instanceof IntegerStamp) {
   133                 }
   141                 }
   134             }
   142             }
   135         }
   143         }
   136 
   144 
   137         if (self == null) {
   145         if (self == null) {
   138             self = new ZeroExtendNode(forValue, inputBits, resultBits);
   146             self = new ZeroExtendNode(forValue, inputBits, resultBits, alwaysPositive);
   139         }
   147         }
   140         return self;
   148         return self;
   141     }
   149     }
   142 
   150 
   143     @Override
   151     @Override