src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java
changeset 58877 aec7bf35d6f5
parent 58533 46b0b7fe255c
equal deleted inserted replaced
58876:1a8d65e71a66 58877:aec7bf35d6f5
    25 package org.graalvm.compiler.nodes.calc;
    25 package org.graalvm.compiler.nodes.calc;
    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.Or;
    29 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Or;
    30 import org.graalvm.compiler.core.common.type.PrimitiveStamp;
    30 import org.graalvm.compiler.core.common.type.IntegerStamp;
    31 import org.graalvm.compiler.core.common.type.Stamp;
    31 import org.graalvm.compiler.core.common.type.Stamp;
    32 import org.graalvm.compiler.graph.NodeClass;
    32 import org.graalvm.compiler.graph.NodeClass;
    33 import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
    33 import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
    34 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
    34 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
    35 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
    35 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
    38 import org.graalvm.compiler.nodes.NodeView;
    38 import org.graalvm.compiler.nodes.NodeView;
    39 import org.graalvm.compiler.nodes.ValueNode;
    39 import org.graalvm.compiler.nodes.ValueNode;
    40 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
    40 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
    41 import org.graalvm.compiler.nodes.util.GraphUtil;
    41 import org.graalvm.compiler.nodes.util.GraphUtil;
    42 
    42 
    43 import jdk.vm.ci.code.CodeUtil;
       
    44 import jdk.vm.ci.meta.Constant;
    43 import jdk.vm.ci.meta.Constant;
    45 import jdk.vm.ci.meta.PrimitiveConstant;
       
    46 
    44 
    47 @NodeInfo(shortName = "|")
    45 @NodeInfo(shortName = "|")
    48 public final class OrNode extends BinaryArithmeticNode<Or> implements BinaryCommutative<ValueNode>, NarrowableArithmeticNode {
    46 public final class OrNode extends BinaryArithmeticNode<Or> implements BinaryCommutative<ValueNode>, NarrowableArithmeticNode {
    49 
    47 
    50     public static final NodeClass<OrNode> TYPE = NodeClass.create(OrNode.class);
    48     public static final NodeClass<OrNode> TYPE = NodeClass.create(OrNode.class);
    51 
    49 
    52     public OrNode(ValueNode x, ValueNode y) {
    50     public OrNode(ValueNode x, ValueNode y) {
    53         super(TYPE, getArithmeticOpTable(x).getOr(), x, y);
    51         super(TYPE, getArithmeticOpTable(x).getOr(), x, y);
    54     }
    52     }
    55 
    53 
       
    54     private OrNode(ValueNode x, ValueNode y, Stamp forcedStamp) {
       
    55         super(TYPE, forcedStamp, x, y);
       
    56     }
       
    57 
       
    58     /**
       
    59      * Create a new XorNode with a forced stamp, without eager folding. This should only be used in
       
    60      * snippet code, where native-image may assign wrong stamps during graph generation.
       
    61      */
       
    62     public static ValueNode createForSnippet(ValueNode x, ValueNode y, Stamp forcedStamp) {
       
    63         return new OrNode(x, y, forcedStamp);
       
    64     }
       
    65 
    56     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
    66     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
    57         BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp(view)).getOr();
    67         BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp(view)).getOr();
    58         Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
    68         Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
    59         ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
    69         ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
    60         if (tryConstantFold != null) {
    70         if (tryConstantFold != null) {
    61             return tryConstantFold;
    71             return tryConstantFold;
    62         }
    72         }
    63         return canonical(null, op, stamp, x, y, view);
    73         return canonical(null, op, x, y, view);
    64     }
    74     }
    65 
    75 
    66     @Override
    76     @Override
    67     protected BinaryOp<Or> getOp(ArithmeticOpTable table) {
    77     protected BinaryOp<Or> getOp(ArithmeticOpTable table) {
    68         return table.getOr();
    78         return table.getOr();
    74         ValueNode ret = super.canonical(tool, forX, forY);
    84         ValueNode ret = super.canonical(tool, forX, forY);
    75         if (ret != this) {
    85         if (ret != this) {
    76             return ret;
    86             return ret;
    77         }
    87         }
    78 
    88 
    79         return canonical(this, getOp(forX, forY), stamp(view), forX, forY, view);
    89         return canonical(this, getOp(forX, forY), forX, forY, view);
    80     }
    90     }
    81 
    91 
    82     private static ValueNode canonical(OrNode self, BinaryOp<Or> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
    92     private static ValueNode canonical(OrNode self, BinaryOp<Or> op, ValueNode forX, ValueNode forY, NodeView view) {
    83         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
    93         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
    84             return forX;
    94             return forX;
    85         }
    95         }
    86         if (forX.isConstant() && !forY.isConstant()) {
    96         if (forX.isConstant() && !forY.isConstant()) {
    87             return new OrNode(forY, forX);
    97             return new OrNode(forY, forX);
    88         }
    98         }
       
    99 
       
   100         Stamp rawXStamp = forX.stamp(view);
       
   101         Stamp rawYStamp = forY.stamp(view);
       
   102         if (rawXStamp instanceof IntegerStamp && rawYStamp instanceof IntegerStamp) {
       
   103             IntegerStamp xStamp = (IntegerStamp) rawXStamp;
       
   104             IntegerStamp yStamp = (IntegerStamp) rawYStamp;
       
   105             if (((~xStamp.downMask()) & yStamp.upMask()) == 0) {
       
   106                 return forX;
       
   107             } else if (((~yStamp.downMask()) & xStamp.upMask()) == 0) {
       
   108                 return forY;
       
   109             }
       
   110         }
       
   111 
    89         if (forY.isConstant()) {
   112         if (forY.isConstant()) {
    90             Constant c = forY.asConstant();
   113             Constant c = forY.asConstant();
    91             if (op.isNeutral(c)) {
   114             if (op.isNeutral(c)) {
    92                 return forX;
   115                 return forX;
    93             }
   116             }
    94 
   117 
    95             if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
       
    96                 long rawY = ((PrimitiveConstant) c).asLong();
       
    97                 long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp));
       
    98                 if ((rawY & mask) == mask) {
       
    99                     return ConstantNode.forIntegerStamp(stamp, mask);
       
   100                 }
       
   101             }
       
   102             return reassociate(self != null ? self : (OrNode) new OrNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
   118             return reassociate(self != null ? self : (OrNode) new OrNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
   103         }
   119         }
       
   120 
   104         if (forX instanceof NotNode && forY instanceof NotNode) {
   121         if (forX instanceof NotNode && forY instanceof NotNode) {
   105             return new NotNode(AndNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
   122             return new NotNode(AndNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
   106         }
   123         }
       
   124 
   107         return self != null ? self : new OrNode(forX, forY).maybeCommuteInputs();
   125         return self != null ? self : new OrNode(forX, forY).maybeCommuteInputs();
   108     }
   126     }
   109 
   127 
   110     @Override
   128     @Override
   111     public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
   129     public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {