< prev index next >

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

Print this page




  66         return canonical(null, op, stamp, x, y, view);
  67     }
  68 
  69     @Override
  70     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
  71         NodeView view = NodeView.from(tool);
  72         ValueNode ret = super.canonical(tool, forX, forY);
  73         if (ret != this) {
  74             return ret;
  75         }
  76 
  77         return canonical(this, getArithmeticOp(), stamp(view), forX, forY, view);
  78     }
  79 
  80     private static ValueNode canonical(RightShiftNode rightShiftNode, ArithmeticOpTable.ShiftOp<Shr> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
  81         RightShiftNode self = rightShiftNode;
  82         if (forX.stamp(view) instanceof IntegerStamp && ((IntegerStamp) forX.stamp(view)).isPositive()) {
  83             return new UnsignedRightShiftNode(forX, forY);
  84         }
  85 









  86         if (forY.isConstant()) {
  87             int amount = forY.asJavaConstant().asInt();
  88             int originalAmout = amount;
  89             int mask = op.getShiftAmountMask(stamp);
  90             amount &= mask;
  91             if (amount == 0) {
  92                 return forX;
  93             }










  94             if (forX instanceof ShiftNode) {
  95                 ShiftNode<?> other = (ShiftNode<?>) forX;
  96                 if (other.getY().isConstant()) {
  97                     int otherAmount = other.getY().asJavaConstant().asInt() & mask;
  98                     if (other instanceof RightShiftNode) {
  99                         int total = amount + otherAmount;
 100                         if (total != (total & mask)) {
 101                             assert other.getX().stamp(view) instanceof IntegerStamp;
 102                             IntegerStamp istamp = (IntegerStamp) other.getX().stamp(view);
 103 
 104                             if (istamp.isPositive()) {
 105                                 return ConstantNode.forIntegerKind(stamp.getStackKind(), 0);
 106                             }
 107                             if (istamp.isStrictlyNegative()) {
 108                                 return ConstantNode.forIntegerKind(stamp.getStackKind(), -1L);
 109                             }
 110 
 111                             /*
 112                              * if we cannot replace both shifts with a constant, replace them by a
 113                              * full shift for this kind




  66         return canonical(null, op, stamp, x, y, view);
  67     }
  68 
  69     @Override
  70     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
  71         NodeView view = NodeView.from(tool);
  72         ValueNode ret = super.canonical(tool, forX, forY);
  73         if (ret != this) {
  74             return ret;
  75         }
  76 
  77         return canonical(this, getArithmeticOp(), stamp(view), forX, forY, view);
  78     }
  79 
  80     private static ValueNode canonical(RightShiftNode rightShiftNode, ArithmeticOpTable.ShiftOp<Shr> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
  81         RightShiftNode self = rightShiftNode;
  82         if (forX.stamp(view) instanceof IntegerStamp && ((IntegerStamp) forX.stamp(view)).isPositive()) {
  83             return new UnsignedRightShiftNode(forX, forY);
  84         }
  85 
  86         Stamp xStampGeneric = forX.stamp(view);
  87         if (xStampGeneric instanceof IntegerStamp) {
  88             IntegerStamp xStamp = (IntegerStamp) xStampGeneric;
  89             if (xStamp.lowerBound() >= -1 && xStamp.upperBound() <= 0) {
  90                 // Right shift by any amount does not change any bit.
  91                 return forX;
  92             }
  93         }
  94 
  95         if (forY.isConstant()) {
  96             int amount = forY.asJavaConstant().asInt();
  97             int originalAmout = amount;
  98             int mask = op.getShiftAmountMask(stamp);
  99             amount &= mask;
 100             if (amount == 0) {
 101                 return forX;
 102             }
 103 
 104             if (xStampGeneric instanceof IntegerStamp) {
 105                 IntegerStamp xStamp = (IntegerStamp) xStampGeneric;
 106 
 107                 if (xStamp.lowerBound() >> amount == xStamp.upperBound() >> amount) {
 108                     // Right shift turns the result of the expression into a constant.
 109                     return ConstantNode.forIntegerKind(stamp.getStackKind(), xStamp.lowerBound() >> amount);
 110                 }
 111             }
 112 
 113             if (forX instanceof ShiftNode) {
 114                 ShiftNode<?> other = (ShiftNode<?>) forX;
 115                 if (other.getY().isConstant()) {
 116                     int otherAmount = other.getY().asJavaConstant().asInt() & mask;
 117                     if (other instanceof RightShiftNode) {
 118                         int total = amount + otherAmount;
 119                         if (total != (total & mask)) {
 120                             assert other.getX().stamp(view) instanceof IntegerStamp;
 121                             IntegerStamp istamp = (IntegerStamp) other.getX().stamp(view);
 122 
 123                             if (istamp.isPositive()) {
 124                                 return ConstantNode.forIntegerKind(stamp.getStackKind(), 0);
 125                             }
 126                             if (istamp.isStrictlyNegative()) {
 127                                 return ConstantNode.forIntegerKind(stamp.getStackKind(), -1L);
 128                             }
 129 
 130                             /*
 131                              * if we cannot replace both shifts with a constant, replace them by a
 132                              * full shift for this kind


< prev index next >