src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java
changeset 58877 aec7bf35d6f5
parent 58533 46b0b7fe255c
equal deleted inserted replaced
58876:1a8d65e71a66 58877:aec7bf35d6f5
    26 
    26 
    27 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
    27 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
    28 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
    28 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
    29 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.And;
    29 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.And;
    30 import org.graalvm.compiler.core.common.type.IntegerStamp;
    30 import org.graalvm.compiler.core.common.type.IntegerStamp;
    31 import org.graalvm.compiler.core.common.type.PrimitiveStamp;
       
    32 import org.graalvm.compiler.core.common.type.Stamp;
    31 import org.graalvm.compiler.core.common.type.Stamp;
    33 import org.graalvm.compiler.graph.NodeClass;
    32 import org.graalvm.compiler.graph.NodeClass;
    34 import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
    33 import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
    35 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
    34 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
    36 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
    35 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
    39 import org.graalvm.compiler.nodes.NodeView;
    38 import org.graalvm.compiler.nodes.NodeView;
    40 import org.graalvm.compiler.nodes.ValueNode;
    39 import org.graalvm.compiler.nodes.ValueNode;
    41 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
    40 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
    42 import org.graalvm.compiler.nodes.util.GraphUtil;
    41 import org.graalvm.compiler.nodes.util.GraphUtil;
    43 
    42 
    44 import jdk.vm.ci.code.CodeUtil;
       
    45 import jdk.vm.ci.meta.Constant;
    43 import jdk.vm.ci.meta.Constant;
    46 import jdk.vm.ci.meta.PrimitiveConstant;
    44 import jdk.vm.ci.meta.PrimitiveConstant;
    47 
    45 
    48 @NodeInfo(shortName = "&")
    46 @NodeInfo(shortName = "&")
    49 public final class AndNode extends BinaryArithmeticNode<And> implements NarrowableArithmeticNode, BinaryCommutative<ValueNode> {
    47 public final class AndNode extends BinaryArithmeticNode<And> implements NarrowableArithmeticNode, BinaryCommutative<ValueNode> {
    59         Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
    57         Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
    60         ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
    58         ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
    61         if (tryConstantFold != null) {
    59         if (tryConstantFold != null) {
    62             return tryConstantFold;
    60             return tryConstantFold;
    63         }
    61         }
    64         return canonical(null, op, stamp, x, y, view);
    62         return canonical(null, op, x, y, view);
    65     }
    63     }
    66 
    64 
    67     @Override
    65     @Override
    68     protected BinaryOp<And> getOp(ArithmeticOpTable table) {
    66     protected BinaryOp<And> getOp(ArithmeticOpTable table) {
    69         return table.getAnd();
    67         return table.getAnd();
    75         if (ret != this) {
    73         if (ret != this) {
    76             return ret;
    74             return ret;
    77         }
    75         }
    78 
    76 
    79         NodeView view = NodeView.from(tool);
    77         NodeView view = NodeView.from(tool);
    80         return canonical(this, getOp(forX, forY), stamp(view), forX, forY, view);
    78         return canonical(this, getOp(forX, forY), forX, forY, view);
    81     }
    79     }
    82 
    80 
    83     private static ValueNode canonical(AndNode self, BinaryOp<And> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
    81     private static ValueNode canonical(AndNode self, BinaryOp<And> op, ValueNode forX, ValueNode forY, NodeView view) {
    84         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
    82         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
    85             return forX;
    83             return forX;
    86         }
    84         }
    87         if (forX.isConstant() && !forY.isConstant()) {
    85         if (forX.isConstant() && !forY.isConstant()) {
    88             return new AndNode(forY, forX);
    86             return new AndNode(forY, forX);
    89         }
    87         }
       
    88 
       
    89         Stamp rawXStamp = forX.stamp(view);
       
    90         Stamp rawYStamp = forY.stamp(view);
       
    91         if (rawXStamp instanceof IntegerStamp && rawYStamp instanceof IntegerStamp) {
       
    92             IntegerStamp xStamp = (IntegerStamp) rawXStamp;
       
    93             IntegerStamp yStamp = (IntegerStamp) rawYStamp;
       
    94             if (((~xStamp.downMask()) & yStamp.upMask()) == 0) {
       
    95                 return forY;
       
    96             } else if (((~yStamp.downMask()) & xStamp.upMask()) == 0) {
       
    97                 return forX;
       
    98             }
       
    99         }
       
   100 
    90         if (forY.isConstant()) {
   101         if (forY.isConstant()) {
    91             Constant c = forY.asConstant();
   102             Constant c = forY.asConstant();
    92             if (op.isNeutral(c)) {
   103             if (op.isNeutral(c)) {
    93                 return forX;
   104                 return forX;
    94             }
   105             }
    95 
   106 
    96             if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
   107             if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
    97                 long rawY = ((PrimitiveConstant) c).asLong();
   108                 long rawY = ((PrimitiveConstant) c).asLong();
    98                 long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp));
       
    99                 if ((rawY & mask) == 0) {
       
   100                     return ConstantNode.forIntegerStamp(stamp, 0);
       
   101                 }
       
   102                 if (forX instanceof SignExtendNode) {
   109                 if (forX instanceof SignExtendNode) {
   103                     SignExtendNode ext = (SignExtendNode) forX;
   110                     SignExtendNode ext = (SignExtendNode) forX;
   104                     if (rawY == ((1L << ext.getInputBits()) - 1)) {
   111                     if (rawY == ((1L << ext.getInputBits()) - 1)) {
   105                         return new ZeroExtendNode(ext.getValue(), ext.getResultBits());
   112                         return new ZeroExtendNode(ext.getValue(), ext.getResultBits());
   106                     }
   113                     }
   107                 }
       
   108                 IntegerStamp xStamp = (IntegerStamp) forX.stamp(view);
       
   109                 if (((xStamp.upMask() | xStamp.downMask()) & ~rawY) == 0) {
       
   110                     // No bits are set which are outside the mask, so the mask will have no effect.
       
   111                     return forX;
       
   112                 }
   114                 }
   113             }
   115             }
   114 
   116 
   115             return reassociate(self != null ? self : (AndNode) new AndNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
   117             return reassociate(self != null ? self : (AndNode) new AndNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
   116         }
   118         }