Commit f8ece9a0 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Add support for Math.round to the JSBuiltinReducer.

We can reduce Math.round(v) to a sequence of

  let i = Float64RoundUp(v);
  let r = i - v;
  return r > 0.5 ? 1.0 + i : i;

if the target supports the Float64RoundUp machine operator (i.e.
roundsd with RoundUp rounding on Intel processors with SSE4.1).

R=jarin@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#33572}
parent 0aa00c1b
......@@ -8,6 +8,7 @@
#include "src/compiler/node-properties.h"
#include "src/compiler/simplified-operator.h"
#include "src/objects-inl.h"
#include "src/type-cache.h"
#include "src/types.h"
namespace v8 {
......@@ -85,10 +86,10 @@ class JSCallReduction {
Node* node_;
};
JSBuiltinReducer::JSBuiltinReducer(Editor* editor, JSGraph* jsgraph)
: AdvancedReducer(editor), jsgraph_(jsgraph) {}
: AdvancedReducer(editor),
jsgraph_(jsgraph),
type_cache_(TypeCache::Get()) {}
// ECMA-262, section 15.8.2.11.
Reduction JSBuiltinReducer::ReduceMathMax(Node* node) {
......@@ -141,6 +142,31 @@ Reduction JSBuiltinReducer::ReduceMathFround(Node* node) {
return NoChange();
}
// ES6 section 20.2.2.28 Math.round ( x )
Reduction JSBuiltinReducer::ReduceMathRound(Node* node) {
JSCallReduction r(node);
if (r.InputsMatchOne(type_cache_.kIntegerOrMinusZeroOrNaN)) {
// Math.round(a:integer \/ -0 \/ NaN) -> a
return Replace(r.left());
}
if (r.InputsMatchOne(Type::Number()) &&
machine()->Float64RoundUp().IsSupported()) {
// Math.round(a:number) -> Select(Float64LessThan(#0.5, Float64Sub(i, a)),
// Float64Sub(i, #1.0), i)
// where i = Float64RoundUp(a)
Node* value = r.left();
Node* integer = graph()->NewNode(machine()->Float64RoundUp().op(), value);
Node* real = graph()->NewNode(machine()->Float64Sub(), integer, value);
return Replace(graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(),
jsgraph()->Float64Constant(0.5), real),
graph()->NewNode(machine()->Float64Sub(), integer,
jsgraph()->Float64Constant(1.0)),
integer));
}
return NoChange();
}
Reduction JSBuiltinReducer::Reduce(Node* node) {
Reduction reduction = NoChange();
......@@ -158,6 +184,9 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
case kMathFround:
reduction = ReduceMathFround(node);
break;
case kMathRound:
reduction = ReduceMathRound(node);
break;
default:
break;
}
......
......@@ -9,6 +9,10 @@
namespace v8 {
namespace internal {
// Forward declarations.
class TypeCache;
namespace compiler {
// Forward declarations.
......@@ -30,6 +34,7 @@ class JSBuiltinReducer final : public AdvancedReducer {
Reduction ReduceMathMax(Node* node);
Reduction ReduceMathImul(Node* node);
Reduction ReduceMathFround(Node* node);
Reduction ReduceMathRound(Node* node);
Graph* graph() const;
JSGraph* jsgraph() const { return jsgraph_; }
......@@ -38,7 +43,8 @@ class JSBuiltinReducer final : public AdvancedReducer {
MachineOperatorBuilder* machine() const;
SimplifiedOperatorBuilder* simplified() const;
JSGraph* jsgraph_;
JSGraph* const jsgraph_;
TypeCache const& type_cache_;
};
} // namespace compiler
......
......@@ -1388,6 +1388,7 @@ class RepresentationSelector {
case IrOpcode::kFloat64RoundDown:
case IrOpcode::kFloat64RoundTruncate:
case IrOpcode::kFloat64RoundTiesAway:
case IrOpcode::kFloat64RoundUp:
return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Float64());
case IrOpcode::kFloat64Equal:
case IrOpcode::kFloat64LessThan:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment