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.

Reply via email to