73 } 74 75 if (forX.isConstant() && !forY.isConstant()) { 76 // we try to swap and canonicalize 77 ValueNode improvement = canonical(tool, forY, forX); 78 if (improvement != this) { 79 return improvement; 80 } 81 // if this fails we only swap 82 return new MulNode(forY, forX); 83 } 84 if (forY.isConstant()) { 85 BinaryOp<Mul> op = getOp(forX, forY); 86 Constant c = forY.asConstant(); 87 if (op.isNeutral(c)) { 88 return forX; 89 } 90 91 if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) { 92 long i = ((PrimitiveConstant) c).asLong(); 93 if (i > 0 && CodeUtil.isPowerOf2(i)) { 94 return new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i))); 95 } 96 if (i == 0) { 97 return ConstantNode.forIntegerStamp(stamp, 0); 98 } 99 } 100 101 if (op.isAssociative()) { 102 // canonicalize expressions like "(a * 1) * 2" 103 return reassociate(this, ValueNode.isConstantPredicate(), forX, forY); 104 } 105 } 106 return this; 107 } 108 109 @Override 110 public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { 111 Value op1 = nodeValueMap.operand(getX()); 112 Value op2 = nodeValueMap.operand(getY()); 113 if (shouldSwapInputs(nodeValueMap)) { 114 Value tmp = op1; 115 op1 = op2; 116 op2 = tmp; 117 } | 73 } 74 75 if (forX.isConstant() && !forY.isConstant()) { 76 // we try to swap and canonicalize 77 ValueNode improvement = canonical(tool, forY, forX); 78 if (improvement != this) { 79 return improvement; 80 } 81 // if this fails we only swap 82 return new MulNode(forY, forX); 83 } 84 if (forY.isConstant()) { 85 BinaryOp<Mul> op = getOp(forX, forY); 86 Constant c = forY.asConstant(); 87 if (op.isNeutral(c)) { 88 return forX; 89 } 90 91 if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) { 92 long i = ((PrimitiveConstant) c).asLong(); 93 94 if (i == 0) { 95 return ConstantNode.forIntegerStamp(stamp, 0); 96 } else if (i == 1) { 97 return forX; 98 } else if (i == -1) { 99 return new NegateNode(forX); 100 } else if (i > 0) { 101 if (CodeUtil.isPowerOf2(i)) { 102 return new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i))); 103 } else if (CodeUtil.isPowerOf2(i - 1)) { 104 return AddNode.create(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i - 1))), forX); 105 } else if (CodeUtil.isPowerOf2(i + 1)) { 106 return SubNode.create(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i + 1))), forX); 107 } 108 } else if (i < 0) { 109 if (CodeUtil.isPowerOf2(-i)) { 110 return new NegateNode(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(-i)))); 111 } 112 } 113 } 114 115 if (op.isAssociative()) { 116 // canonicalize expressions like "(a * 1) * 2" 117 return reassociate(this, ValueNode.isConstantPredicate(), forX, forY); 118 } 119 } 120 return this; 121 } 122 123 @Override 124 public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { 125 Value op1 = nodeValueMap.operand(getX()); 126 Value op2 = nodeValueMap.operand(getY()); 127 if (shouldSwapInputs(nodeValueMap)) { 128 Value tmp = op1; 129 op1 = op2; 130 op2 = tmp; 131 } |