[turbofan] Use builtin inlining mechanism for Math.abs and Math.sqrt.
authorbmeurer <bmeurer@chromium.org>
Fri, 13 Mar 2015 07:06:02 +0000 (00:06 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 13 Mar 2015 07:06:15 +0000 (07:06 +0000)
Reduces the amount of custom support code for Math functions in TurboFan
and allows for more general inlining (i.e. independent of parameter
types).

BUG=v8:3952
LOG=n
R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/1004083002

Cr-Commit-Position: refs/heads/master@{#27172}

12 files changed:
src/compiler/js-builtin-reducer.cc
src/compiler/js-builtin-reducer.h
src/compiler/js-intrinsic-lowering.cc
src/compiler/js-intrinsic-lowering.h
src/compiler/typer.cc
src/hydrogen.cc
src/hydrogen.h
src/math.js
src/runtime/runtime-maths.cc
src/runtime/runtime.h
src/x87/lithium-codegen-x87.cc
test/unittests/compiler/js-builtin-reducer-unittest.cc

index e2d12f0..2a032db 100644 (file)
@@ -100,38 +100,6 @@ JSBuiltinReducer::JSBuiltinReducer(JSGraph* jsgraph)
     : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
 
 
-// ECMA-262, section 15.8.2.1.
-Reduction JSBuiltinReducer::ReduceMathAbs(Node* node) {
-  JSCallReduction r(node);
-  if (r.InputsMatchOne(Type::Unsigned32())) {
-    // Math.abs(a:uint32) -> a
-    return Replace(r.left());
-  }
-  if (r.InputsMatchOne(Type::Number())) {
-    // Math.abs(a:number) -> (a > 0 ? a : 0 - a)
-    Node* const value = r.left();
-    Node* const zero = jsgraph()->ZeroConstant();
-    return Replace(graph()->NewNode(
-        common()->Select(kMachNone),
-        graph()->NewNode(simplified()->NumberLessThan(), zero, value), value,
-        graph()->NewNode(simplified()->NumberSubtract(), zero, value)));
-  }
-  return NoChange();
-}
-
-
-// ECMA-262, section 15.8.2.17.
-Reduction JSBuiltinReducer::ReduceMathSqrt(Node* node) {
-  JSCallReduction r(node);
-  if (r.InputsMatchOne(Type::Number())) {
-    // Math.sqrt(a:number) -> Float64Sqrt(a)
-    Node* value = graph()->NewNode(machine()->Float64Sqrt(), r.left());
-    return Replace(value);
-  }
-  return NoChange();
-}
-
-
 // ECMA-262, section 15.8.2.11.
 Reduction JSBuiltinReducer::ReduceMathMax(Node* node) {
   JSCallReduction r(node);
@@ -190,10 +158,6 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
   // Dispatch according to the BuiltinFunctionId if present.
   if (!r.HasBuiltinFunctionId()) return NoChange();
   switch (r.GetBuiltinFunctionId()) {
-    case kMathAbs:
-      return ReplaceWithPureReduction(node, ReduceMathAbs(node));
-    case kMathSqrt:
-      return ReplaceWithPureReduction(node, ReduceMathSqrt(node));
     case kMathMax:
       return ReplaceWithPureReduction(node, ReduceMathMax(node));
     case kMathImul:
index 60b9e14..42221e9 100644 (file)
@@ -26,8 +26,6 @@ class JSBuiltinReducer FINAL : public Reducer {
   Reduction Reduce(Node* node) FINAL;
 
  private:
-  Reduction ReduceMathAbs(Node* node);
-  Reduction ReduceMathSqrt(Node* node);
   Reduction ReduceMathMax(Node* node);
   Reduction ReduceMathImul(Node* node);
   Reduction ReduceMathFround(Node* node);
index 317421f..ebe2e4e 100644 (file)
@@ -42,6 +42,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
       return ReduceInlineIsInstanceType(node, JS_REGEXP_TYPE);
     case Runtime::kInlineMathFloor:
       return ReduceInlineMathFloor(node);
+    case Runtime::kInlineMathSqrt:
+      return ReduceInlineMathSqrt(node);
     case Runtime::kInlineValueOf:
       return ReduceInlineValueOf(node);
     default:
@@ -170,6 +172,11 @@ Reduction JSIntrinsicLowering::ReduceInlineMathFloor(Node* node) {
 }
 
 
+Reduction JSIntrinsicLowering::ReduceInlineMathSqrt(Node* node) {
+  return Change(node, machine()->Float64Sqrt());
+}
+
+
 Reduction JSIntrinsicLowering::ReduceInlineValueOf(Node* node) {
   // if (%_IsSmi(value)) {
   //   return value;
index 493e962..3a910fd 100644 (file)
@@ -35,6 +35,7 @@ class JSIntrinsicLowering FINAL : public Reducer {
   Reduction ReduceInlineDoubleLo(Node* node);
   Reduction ReduceInlineDoubleHi(Node* node);
   Reduction ReduceInlineMathFloor(Node* node);
+  Reduction ReduceInlineMathSqrt(Node* node);
   Reduction ReduceInlineValueOf(Node* node);
 
   Reduction Change(Node* node, const Operator* op);
index 3f9b105..f3fdaad 100644 (file)
@@ -1511,6 +1511,7 @@ Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) {
       return Bounds(Type::None(zone()), Type::Signed32());
     case Runtime::kInlineConstructDouble:
     case Runtime::kInlineMathFloor:
+    case Runtime::kInlineMathSqrt:
       return Bounds(Type::None(zone()), Type::Number());
     default:
       break;
index 810d3ff..5c6b5cd 100644 (file)
@@ -12012,7 +12012,7 @@ void HOptimizedGraphBuilder::GenerateMathLogRT(CallRuntime* call) {
 }
 
 
-void HOptimizedGraphBuilder::GenerateMathSqrtRT(CallRuntime* call) {
+void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
   DCHECK(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
index 2e7a5dd..c454a28 100644 (file)
@@ -2213,7 +2213,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
   F(DoubleHi)                          \
   F(DoubleLo)                          \
   F(MathFloor)                         \
-  F(MathSqrtRT)                        \
+  F(MathSqrt)                          \
   F(MathLogRT)                         \
   /* ES6 Collections */                \
   F(MapClear)                          \
index d7e5f94..ed9bdbd 100644 (file)
@@ -23,10 +23,9 @@ var GlobalArray = global.Array;
 
 // ECMA 262 - 15.8.2.1
 function MathAbs(x) {
-  if (%_IsSmi(x)) return x >= 0 ? x : -x;
-  x = TO_NUMBER_INLINE(x);
-  if (x === 0) return 0;  // To handle -0.
-  return x > 0 ? x : -x;
+  x = +x;
+  if (x > 0) return x;
+  return 0 - x;
 }
 
 // ECMA 262 - 15.8.2.2
@@ -148,7 +147,7 @@ function MathRound(x) {
 
 // ECMA 262 - 15.8.2.17
 function MathSqrt(x) {
-  return %_MathSqrtRT(TO_NUMBER_INLINE(x));
+  return %_MathSqrt(+x);
 }
 
 // Non-standard extension.
@@ -191,9 +190,9 @@ function MathAsinh(x) {
   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
   // Idempotent for NaN, +/-0 and +/-Infinity.
   if (x === 0 || !NUMBER_IS_FINITE(x)) return x;
-  if (x > 0) return MathLog(x + MathSqrt(x * x + 1));
+  if (x > 0) return MathLog(x + %_MathSqrt(x * x + 1));
   // This is to prevent numerical errors caused by large negative x.
-  return -MathLog(-x + MathSqrt(x * x + 1));
+  return -MathLog(-x + %_MathSqrt(x * x + 1));
 }
 
 // ES6 draft 09-27-13, section 20.2.2.3.
@@ -202,7 +201,7 @@ function MathAcosh(x) {
   if (x < 1) return NAN;
   // Idempotent for NaN and +Infinity.
   if (!NUMBER_IS_FINITE(x)) return x;
-  return MathLog(x + MathSqrt(x + 1) * MathSqrt(x - 1));
+  return MathLog(x + %_MathSqrt(x + 1) * %_MathSqrt(x - 1));
 }
 
 // ES6 draft 09-27-13, section 20.2.2.7.
@@ -244,7 +243,7 @@ function MathHypot(x, y) {  // Function length is 2.
     compensation = (preliminary - sum) - summand;
     sum = preliminary;
   }
-  return MathSqrt(sum) * max;
+  return %_MathSqrt(sum) * max;
 }
 
 // ES6 draft 09-27-13, section 20.2.2.16.
@@ -350,9 +349,11 @@ InstallFunctions(Math, DONT_ENUM, GlobalArray(
   "cbrt", MathCbrt
 ));
 
+%SetInlineBuiltinFlag(MathAbs);
 %SetInlineBuiltinFlag(MathCeil);
 %SetInlineBuiltinFlag(MathFloor);
 %SetInlineBuiltinFlag(MathRandom);
+%SetInlineBuiltinFlag(MathSqrt);
 
 // Expose to the global scope.
 $abs = MathAbs;
index 807791b..a4435e0 100644 (file)
@@ -207,7 +207,7 @@ RUNTIME_FUNCTION(Runtime_RoundNumber) {
 }
 
 
-RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
+RUNTIME_FUNCTION(Runtime_MathSqrt) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 1);
   isolate->counters()->math_sqrt()->Increment();
index ce76c6d..d820490 100644 (file)
@@ -694,7 +694,7 @@ namespace internal {
   F(DoubleHi, 1, 1)                       \
   F(DoubleLo, 1, 1)                       \
   F(MathFloor, 1, 1)                      \
-  F(MathSqrtRT, 1, 1)                     \
+  F(MathSqrt, 1, 1)                       \
   F(MathLogRT, 1, 1)                      \
   /* ES6 Collections */                   \
   F(MapClear, 1, 1)                       \
index 8fd8f5b..25c8e35 100644 (file)
@@ -4104,7 +4104,7 @@ void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
 
     __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
     __ push(temp_result);
-    __ CallRuntimeSaveDoubles(Runtime::kMathSqrtRT);
+    __ CallRuntimeSaveDoubles(Runtime::kMathSqrt);
     RecordSafepointWithRegisters(instr->pointer_map(), 1,
                                  Safepoint::kNoLazyDeopt);
     __ StoreToSafepointRegisterSlot(temp_result, eax);
index ee9f960..c98bc6c 100644 (file)
@@ -62,58 +62,6 @@ Type* const kNumberTypes[] = {
 
 
 // -----------------------------------------------------------------------------
-// Math.abs
-
-
-TEST_F(JSBuiltinReducerTest, MathAbs) {
-  Handle<JSFunction> f = MathFunction("abs");
-
-  TRACED_FOREACH(Type*, t0, kNumberTypes) {
-    Node* p0 = Parameter(t0, 0);
-    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
-    Node* call =
-        graph()->NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
-                         fun, UndefinedConstant(), p0);
-    Reduction r = Reduce(call);
-
-    if (t0->Is(Type::Unsigned32())) {
-      ASSERT_TRUE(r.Changed());
-      EXPECT_THAT(r.replacement(), p0);
-    } else {
-      Capture<Node*> branch;
-      ASSERT_TRUE(r.Changed());
-      EXPECT_THAT(
-          r.replacement(),
-          IsSelect(kMachNone,
-                   IsNumberLessThan(IsNumberConstant(BitEq(0.0)), p0), p0,
-                   IsNumberSubtract(IsNumberConstant(BitEq(0.0)), p0)));
-    }
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Math.sqrt
-
-
-TEST_F(JSBuiltinReducerTest, MathSqrt) {
-  Handle<JSFunction> f = MathFunction("sqrt");
-
-  TRACED_FOREACH(Type*, t0, kNumberTypes) {
-    Node* p0 = Parameter(t0, 0);
-    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
-    Node* call =
-        graph()->NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
-                         fun, UndefinedConstant(), p0);
-    Reduction r = Reduce(call);
-
-    ASSERT_TRUE(r.Changed());
-    EXPECT_THAT(r.replacement(), IsFloat64Sqrt(p0));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
 // Math.max