63 public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { 64 NodeView view = NodeView.from(tool); 65 ValueNode ret = super.canonical(tool, forX, forY); 66 if (ret != this) { 67 return ret; 68 } 69 70 return canonical(this, this.getArithmeticOp(), this.stamp(view), forX, forY, view); 71 } 72 73 @SuppressWarnings("unused") 74 private static ValueNode canonical(UnsignedRightShiftNode node, ArithmeticOpTable.ShiftOp<UShr> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) { 75 if (forY.isConstant()) { 76 int amount = forY.asJavaConstant().asInt(); 77 int originalAmout = amount; 78 int mask = op.getShiftAmountMask(stamp); 79 amount &= mask; 80 if (amount == 0) { 81 return forX; 82 } 83 if (forX instanceof ShiftNode) { 84 ShiftNode<?> other = (ShiftNode<?>) forX; 85 if (other.getY().isConstant()) { 86 int otherAmount = other.getY().asJavaConstant().asInt() & mask; 87 if (other instanceof UnsignedRightShiftNode) { 88 int total = amount + otherAmount; 89 if (total != (total & mask)) { 90 return ConstantNode.forIntegerKind(stamp.getStackKind(), 0); 91 } 92 return new UnsignedRightShiftNode(other.getX(), ConstantNode.forInt(total)); 93 } else if (other instanceof LeftShiftNode && otherAmount == amount) { 94 if (stamp.getStackKind() == JavaKind.Long) { 95 return new AndNode(other.getX(), ConstantNode.forLong(-1L >>> amount)); 96 } else { 97 assert stamp.getStackKind() == JavaKind.Int; 98 return new AndNode(other.getX(), ConstantNode.forInt(-1 >>> amount)); 99 } 100 } 101 } 102 } | 63 public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { 64 NodeView view = NodeView.from(tool); 65 ValueNode ret = super.canonical(tool, forX, forY); 66 if (ret != this) { 67 return ret; 68 } 69 70 return canonical(this, this.getArithmeticOp(), this.stamp(view), forX, forY, view); 71 } 72 73 @SuppressWarnings("unused") 74 private static ValueNode canonical(UnsignedRightShiftNode node, ArithmeticOpTable.ShiftOp<UShr> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) { 75 if (forY.isConstant()) { 76 int amount = forY.asJavaConstant().asInt(); 77 int originalAmout = amount; 78 int mask = op.getShiftAmountMask(stamp); 79 amount &= mask; 80 if (amount == 0) { 81 return forX; 82 } 83 84 Stamp xStampGeneric = forX.stamp(view); 85 if (xStampGeneric instanceof IntegerStamp) { 86 IntegerStamp xStamp = (IntegerStamp) xStampGeneric; 87 88 if (xStamp.lowerBound() >>> amount == xStamp.upperBound() >>> amount) { 89 // The result of the shift is constant. 90 return ConstantNode.forIntegerKind(stamp.getStackKind(), xStamp.lowerBound() >>> amount); 91 } 92 93 if (amount == xStamp.getBits() - 1 && xStamp.lowerBound() == -1 && xStamp.upperBound() == 0) { 94 // Shift is equivalent to a negation, i.e., turns -1 into 1 and keeps 0 at 0. 95 return NegateNode.create(forX, view); 96 } 97 } 98 99 if (forX instanceof ShiftNode) { 100 ShiftNode<?> other = (ShiftNode<?>) forX; 101 if (other.getY().isConstant()) { 102 int otherAmount = other.getY().asJavaConstant().asInt() & mask; 103 if (other instanceof UnsignedRightShiftNode) { 104 int total = amount + otherAmount; 105 if (total != (total & mask)) { 106 return ConstantNode.forIntegerKind(stamp.getStackKind(), 0); 107 } 108 return new UnsignedRightShiftNode(other.getX(), ConstantNode.forInt(total)); 109 } else if (other instanceof LeftShiftNode && otherAmount == amount) { 110 if (stamp.getStackKind() == JavaKind.Long) { 111 return new AndNode(other.getX(), ConstantNode.forLong(-1L >>> amount)); 112 } else { 113 assert stamp.getStackKind() == JavaKind.Int; 114 return new AndNode(other.getX(), ConstantNode.forInt(-1 >>> amount)); 115 } 116 } 117 } 118 } |