Revision: 19036
Author: [email protected]
Date: Mon Feb 3 16:49:11 2014 UTC
Log: A64: Add support for SMI representation to MulConstI. Also add a
test.
[email protected]
Review URL: https://codereview.chromium.org/152133003
http://code.google.com/p/v8/source/detail?r=19036
Added:
/branches/experimental/a64/test/mjsunit/smi-mul-const.js
Modified:
/branches/experimental/a64/src/a64/lithium-a64.cc
/branches/experimental/a64/src/a64/lithium-a64.h
/branches/experimental/a64/src/a64/lithium-codegen-a64.cc
=======================================
--- /dev/null
+++ /branches/experimental/a64/test/mjsunit/smi-mul-const.js Mon Feb 3
16:49:11 2014 UTC
@@ -0,0 +1,87 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --noalways-opt
+
+function check(func, input, expected) {
+ func(-1);
+ func(-1);
+ %OptimizeFunctionOnNextCall(func);
+ assertEquals(expected, func(input));
+ assertOptimized(func);
+}
+
+function mul_by_neg_1(a) { return a * -1; }
+function mul_by_0(a) { return a * 0; }
+function mul_by_1(a) { return a * 1; }
+function mul_by_2(a) { return a * 2; }
+
+check(mul_by_neg_1, 2, -2);
+check(mul_by_0, 2, 0);
+check(mul_by_1, 2, 2);
+check(mul_by_2, 2, 4);
+
+function limit_range(a) {
+ // Limit the range of 'a' to enable no-overflow optimizations.
+ return Math.max(Math.min(a | 0, 10), -10);
+}
+
+function mul_by_neg_127(a) { return limit_range(a) * -127; }
+function mul_by_neg_128(a) { return limit_range(a) * -128; }
+function mul_by_neg_129(a) { return limit_range(a) * -129; }
+function mul_by_1023(a) { return limit_range(a) * 1023; }
+function mul_by_1024(a) { return limit_range(a) * 1024; }
+function mul_by_1025(a) { return limit_range(a) * 1025; }
+
+check(mul_by_neg_127, 2, -254);
+check(mul_by_neg_128, 2, -256);
+check(mul_by_neg_129, 2, -258);
+check(mul_by_1023, 2, 2046);
+check(mul_by_1024, 2, 2048);
+check(mul_by_1025, 2, 2050);
+
+// Deopt on minus zero.
+assertEquals(-0, mul_by_neg_128(0));
+assertUnoptimized(mul_by_neg_128);
+assertEquals(-0, mul_by_2(-0));
+assertUnoptimized(mul_by_2);
+
+// Deopt on overflow.
+
+// 2^30 is a smi boundary on arm and ia32.
+var two_30 = 1 << 30;
+// 2^31 is a smi boundary on arm64 and x64.
+var two_31 = 2 * two_30;
+
+// TODO(rmcilroy): replace after r16361 with: if (%IsValidSmi(two_31)) {
+if (true) {
+ assertEquals(two_31, mul_by_neg_1(-two_31));
+ assertUnoptimized(mul_by_neg_1);
+} else {
+ assertEquals(two_30, mul_by_neg_1(-two_30));
+ assertUnoptimized(mul_by_neg_1);
+}
=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.cc Mon Feb 3 16:47:02
2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-a64.cc Mon Feb 3 16:49:11
2014 UTC
@@ -1858,26 +1858,10 @@
LInstruction* LChunkBuilder::DoMul(HMul* instr) {
- if (instr->representation().IsSmi()) {
- // TODO(jbramley): Implement LMulConstS, then merge this into the
Integer32
- // case.
+ if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
- bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
- bool bailout_on_minus_zero =
instr->CheckFlag(HValue::kBailoutOnMinusZero);
- bool needs_environment = can_overflow || bailout_on_minus_zero;
-
- LOperand* left = UseRegister(instr->BetterLeftOperand());
- LOperand* right = UseRegister(instr->BetterRightOperand());
-
- LMulS* mul = new(zone()) LMulS(left, right);
- if (needs_environment) AssignEnvironment(mul);
- return DefineAsRegister(mul);
- } else if (instr->representation().IsSmiOrInteger32()) {
-
ASSERT(instr->left()->representation().Equals(instr->representation()));
-
ASSERT(instr->right()->representation().Equals(instr->representation()));
-
bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
bool bailout_on_minus_zero =
instr->CheckFlag(HValue::kBailoutOnMinusZero);
bool needs_environment = can_overflow || bailout_on_minus_zero;
@@ -1902,18 +1886,25 @@
IsPowerOf2(constant_abs + 1) ||
IsPowerOf2(constant_abs - 1)))) {
LConstantOperand* right = UseConstant(most_const);
- LMulConstI* mul = new(zone()) LMulConstI(left, right);
+ LMulConstIS* mul = new(zone()) LMulConstIS(left, right);
if (needs_environment) AssignEnvironment(mul);
return DefineAsRegister(mul);
}
}
- // LMulI can handle all cases, but it requires that a register is
allocated
- // for the second operand.
- LOperand* right = UseRegisterAtStart(most_const);
- LMulI* mul = new(zone()) LMulI(left, right);
- if (needs_environment) AssignEnvironment(mul);
- return DefineAsRegister(mul);
+ // LMulI/S can handle all cases, but it requires that a register is
+ // allocated for the second operand.
+ LInstruction* result;
+ if (instr->representation().IsSmi()) {
+ // TODO(jbramley/rmcilroy): Fix LMulS so we can UseRegisterAtStart
here.
+ LOperand* right = UseRegister(most_const);
+ result = DefineAsRegister(new(zone()) LMulS(left, right));
+ } else {
+ LOperand* right = UseRegisterAtStart(most_const);
+ result = DefineAsRegister(new(zone()) LMulI(left, right));
+ }
+ if (needs_environment) AssignEnvironment(result);
+ return result;
} else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::MUL, instr);
} else {
=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.h Mon Feb 3 16:47:02
2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-a64.h Mon Feb 3 16:49:11
2014 UTC
@@ -147,7 +147,7 @@
V(MathSqrt) \
V(MathTan) \
V(ModI) \
- V(MulConstI) \
+ V(MulConstIS) \
V(MulI) \
V(MulS) \
V(NumberTagD) \
@@ -1961,9 +1961,9 @@
};
-class LMulConstI: public LTemplateInstruction<1, 2, 0> {
+class LMulConstIS: public LTemplateInstruction<1, 2, 0> {
public:
- LMulConstI(LOperand* left, LConstantOperand* right) {
+ LMulConstIS(LOperand* left, LConstantOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
@@ -1971,7 +1971,7 @@
LOperand* left() { return inputs_[0]; }
LConstantOperand* right() { return LConstantOperand::cast(inputs_[1]); }
- DECLARE_CONCRETE_INSTRUCTION(MulConstI, "mul-const-i")
+ DECLARE_CONCRETE_INSTRUCTION(MulConstIS, "mul-const-i-s")
DECLARE_HYDROGEN_ACCESSOR(Mul)
};
=======================================
--- /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Mon Feb 3
16:47:02 2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Mon Feb 3
16:49:11 2014 UTC
@@ -4117,11 +4117,13 @@
}
-void LCodeGen::DoMulConstI(LMulConstI* instr) {
- // TODO(jbramley): Support smi operations (or make a separate
DoMulConstS).
-
- Register result = ToRegister32(instr->result());
- Register left = ToRegister32(instr->left());
+void LCodeGen::DoMulConstIS(LMulConstIS* instr) {
+ ASSERT(instr->hydrogen()->representation().IsSmiOrInteger32());
+ bool is_smi = instr->hydrogen()->representation().IsSmi();
+ Register result =
+ is_smi ? ToRegister(instr->result()) : ToRegister32(instr->result());
+ Register left =
+ is_smi ? ToRegister(instr->left()) : ToRegister32(instr->left()) ;
int32_t right = ToInteger32(instr->right());
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.