| Index: src/compiler/js-builtin-reducer.cc
|
| diff --git a/src/compiler/js-builtin-reducer.cc b/src/compiler/js-builtin-reducer.cc
|
| index 51d16b73a7ac966e86628214608d62927cd34bd6..d2759b5f5b7809bb5a723356b69cfd50cb2803c2 100644
|
| --- a/src/compiler/js-builtin-reducer.cc
|
| +++ b/src/compiler/js-builtin-reducer.cc
|
| @@ -91,41 +91,28 @@ JSBuiltinReducer::JSBuiltinReducer(Editor* editor, JSGraph* jsgraph)
|
| jsgraph_(jsgraph),
|
| type_cache_(TypeCache::Get()) {}
|
|
|
| -// ECMA-262, section 15.8.2.11.
|
| -Reduction JSBuiltinReducer::ReduceMathMax(Node* node) {
|
| +// ES6 section 20.2.2.6 Math.atan ( x )
|
| +Reduction JSBuiltinReducer::ReduceMathAtan(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchZero()) {
|
| - // Math.max() -> -Infinity
|
| - return Replace(jsgraph()->Constant(-V8_INFINITY));
|
| - }
|
| - if (r.InputsMatchOne(Type::Number())) {
|
| - // Math.max(a:number) -> a
|
| - return Replace(r.left());
|
| - }
|
| - if (r.InputsMatchAll(Type::Integral32())) {
|
| - // Math.max(a:int32, b:int32, ...)
|
| - Node* value = r.GetJSCallInput(0);
|
| - for (int i = 1; i < r.GetJSCallArity(); i++) {
|
| - Node* const input = r.GetJSCallInput(i);
|
| - value = graph()->NewNode(
|
| - common()->Select(MachineRepresentation::kNone),
|
| - graph()->NewNode(simplified()->NumberLessThan(), input, value), value,
|
| - input);
|
| - }
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.atan(a:plain-primitive) -> NumberAtan(ToNumber(a))
|
| + Node* input = ToNumber(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->NumberAtan(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| }
|
|
|
| -// ES6 section 20.2.2.19 Math.imul ( x, y )
|
| -Reduction JSBuiltinReducer::ReduceMathImul(Node* node) {
|
| +// ES6 section 20.2.2.8 Math.atan2 ( y, x )
|
| +Reduction JSBuiltinReducer::ReduceMathAtan2(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchTwo(Type::Number(), Type::Number())) {
|
| - // Math.imul(a:number, b:number) -> NumberImul(NumberToUint32(a),
|
| - // NumberToUint32(b))
|
| - Node* a = graph()->NewNode(simplified()->NumberToUint32(), r.left());
|
| - Node* b = graph()->NewNode(simplified()->NumberToUint32(), r.right());
|
| - Node* value = graph()->NewNode(simplified()->NumberImul(), a, b);
|
| + if (r.InputsMatchTwo(Type::PlainPrimitive(), Type::PlainPrimitive())) {
|
| + // Math.atan2(a:plain-primitive,
|
| + // b:plain-primitive) -> NumberAtan2(ToNumber(a),
|
| + // ToNumber(b))
|
| + Node* left = ToNumber(r.left());
|
| + Node* right = ToNumber(r.right());
|
| + Node* value = graph()->NewNode(simplified()->NumberAtan2(), left, right);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| @@ -134,9 +121,10 @@ Reduction JSBuiltinReducer::ReduceMathImul(Node* node) {
|
| // ES6 section 20.2.2.10 Math.ceil ( x )
|
| Reduction JSBuiltinReducer::ReduceMathCeil(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchOne(Type::Number())) {
|
| - // Math.ceil(a:number) -> NumberCeil(a)
|
| - Node* value = graph()->NewNode(simplified()->NumberCeil(), r.left());
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.ceil(a:plain-primitive) -> NumberCeil(ToNumber(a))
|
| + Node* input = ToNumber(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->NumberCeil(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| @@ -145,84 +133,127 @@ Reduction JSBuiltinReducer::ReduceMathCeil(Node* node) {
|
| // ES6 section 20.2.2.11 Math.clz32 ( x )
|
| Reduction JSBuiltinReducer::ReduceMathClz32(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchOne(Type::Unsigned32())) {
|
| - // Math.clz32(a:unsigned32) -> NumberClz32(a)
|
| - Node* value = graph()->NewNode(simplified()->NumberClz32(), r.left());
|
| - return Replace(value);
|
| - }
|
| - if (r.InputsMatchOne(Type::Number())) {
|
| - // Math.clz32(a:number) -> NumberClz32(NumberToUint32(a))
|
| - Node* value = graph()->NewNode(
|
| - simplified()->NumberClz32(),
|
| - graph()->NewNode(simplified()->NumberToUint32(), r.left()));
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.clz32(a:plain-primitive) -> NumberClz32(ToUint32(a))
|
| + Node* input = ToUint32(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->NumberClz32(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| }
|
|
|
| -// ES6 draft 08-24-14, section 20.2.2.16.
|
| +// ES6 section 20.2.2.16 Math.floor ( x )
|
| Reduction JSBuiltinReducer::ReduceMathFloor(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchOne(Type::Number())) {
|
| - // Math.floor(a:number) -> NumberFloor(a)
|
| - Node* value = graph()->NewNode(simplified()->NumberFloor(), r.left());
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.floor(a:plain-primitive) -> NumberFloor(ToNumber(a))
|
| + Node* input = ToNumber(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->NumberFloor(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| }
|
|
|
| -// ES6 draft 08-24-14, section 20.2.2.17.
|
| +// ES6 section 20.2.2.17 Math.fround ( x )
|
| Reduction JSBuiltinReducer::ReduceMathFround(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchOne(Type::NumberOrUndefined())) {
|
| - // Math.fround(a:number) -> TruncateFloat64ToFloat32(a)
|
| - Node* value =
|
| - graph()->NewNode(machine()->TruncateFloat64ToFloat32(), r.left());
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.fround(a:plain-primitive) -> NumberFround(ToNumber(a))
|
| + Node* input = ToNumber(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->NumberFround(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| }
|
|
|
| -// ES6 section 20.2.2.6 Math.atan ( x )
|
| -Reduction JSBuiltinReducer::ReduceMathAtan(Node* node) {
|
| +// ES6 section 20.2.2.19 Math.imul ( x, y )
|
| +Reduction JSBuiltinReducer::ReduceMathImul(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchOne(Type::Number())) {
|
| - // Math.atan(a:number) -> NumberAtan(a)
|
| - Node* value = graph()->NewNode(simplified()->NumberAtan(), r.left());
|
| + if (r.InputsMatchTwo(Type::PlainPrimitive(), Type::PlainPrimitive())) {
|
| + // Math.imul(a:plain-primitive,
|
| + // b:plain-primitive) -> NumberImul(ToUint32(a),
|
| + // ToUint32(b))
|
| + Node* left = ToUint32(r.left());
|
| + Node* right = ToUint32(r.right());
|
| + Node* value = graph()->NewNode(simplified()->NumberImul(), left, right);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| }
|
|
|
| -// ES6 section 20.2.2.8 Math.atan2 ( y, x )
|
| -Reduction JSBuiltinReducer::ReduceMathAtan2(Node* node) {
|
| +// ES6 section 20.2.2.20 Math.log ( x )
|
| +Reduction JSBuiltinReducer::ReduceMathLog(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchTwo(Type::Number(), Type::Number())) {
|
| - // Math.atan2(a:number, b:number) -> NumberAtan2(a, b)
|
| - Node* value =
|
| - graph()->NewNode(simplified()->NumberAtan2(), r.left(), r.right());
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.log(a:plain-primitive) -> NumberLog(ToNumber(a))
|
| + Node* input = ToNumber(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->NumberLog(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| }
|
|
|
| -// ES6 section 20.2.2.20 Math.log ( x )
|
| -Reduction JSBuiltinReducer::ReduceMathLog(Node* node) {
|
| +// ES6 section 20.2.2.21 Math.log1p ( x )
|
| +Reduction JSBuiltinReducer::ReduceMathLog1p(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchOne(Type::Number())) {
|
| - // Math.log(a:number) -> NumberLog(a)
|
| - Node* value = graph()->NewNode(simplified()->NumberLog(), r.left());
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.log1p(a:plain-primitive) -> NumberLog1p(ToNumber(a))
|
| + Node* input = ToNumber(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->NumberLog1p(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| }
|
|
|
| -// ES6 section 20.2.2.21 Math.log1p ( x )
|
| -Reduction JSBuiltinReducer::ReduceMathLog1p(Node* node) {
|
| +// ES6 section 20.2.2.24 Math.max ( value1, value2, ...values )
|
| +Reduction JSBuiltinReducer::ReduceMathMax(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchOne(Type::Number())) {
|
| - // Math.log1p(a:number) -> NumberLog1p(a)
|
| - Node* value = graph()->NewNode(simplified()->NumberLog1p(), r.left());
|
| + if (r.InputsMatchZero()) {
|
| + // Math.max() -> -Infinity
|
| + return Replace(jsgraph()->Constant(-V8_INFINITY));
|
| + }
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.max(a:plain-primitive) -> ToNumber(a)
|
| + Node* value = ToNumber(r.GetJSCallInput(0));
|
| + return Replace(value);
|
| + }
|
| + if (r.InputsMatchAll(Type::Integral32())) {
|
| + // Math.max(a:int32, b:int32, ...)
|
| + Node* value = r.GetJSCallInput(0);
|
| + for (int i = 1; i < r.GetJSCallArity(); i++) {
|
| + Node* const input = r.GetJSCallInput(i);
|
| + value = graph()->NewNode(
|
| + common()->Select(MachineRepresentation::kNone),
|
| + graph()->NewNode(simplified()->NumberLessThan(), input, value), value,
|
| + input);
|
| + }
|
| + return Replace(value);
|
| + }
|
| + return NoChange();
|
| +}
|
| +
|
| +// ES6 section 20.2.2.25 Math.min ( value1, value2, ...values )
|
| +Reduction JSBuiltinReducer::ReduceMathMin(Node* node) {
|
| + JSCallReduction r(node);
|
| + if (r.InputsMatchZero()) {
|
| + // Math.min() -> Infinity
|
| + return Replace(jsgraph()->Constant(V8_INFINITY));
|
| + }
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.min(a:plain-primitive) -> ToNumber(a)
|
| + Node* value = ToNumber(r.GetJSCallInput(0));
|
| + return Replace(value);
|
| + }
|
| + if (r.InputsMatchAll(Type::Integral32())) {
|
| + // Math.min(a:int32, b:int32, ...)
|
| + Node* value = r.GetJSCallInput(0);
|
| + for (int i = 1; i < r.GetJSCallArity(); i++) {
|
| + Node* const input = r.GetJSCallInput(i);
|
| + value = graph()->NewNode(
|
| + common()->Select(MachineRepresentation::kNone),
|
| + graph()->NewNode(simplified()->NumberLessThan(), input, value), input,
|
| + value);
|
| + }
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| @@ -231,9 +262,10 @@ Reduction JSBuiltinReducer::ReduceMathLog1p(Node* node) {
|
| // ES6 section 20.2.2.28 Math.round ( x )
|
| Reduction JSBuiltinReducer::ReduceMathRound(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchOne(Type::Number())) {
|
| - // Math.round(a:number) -> NumberRound(a)
|
| - Node* value = graph()->NewNode(simplified()->NumberRound(), r.left());
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.round(a:plain-primitive) -> NumberRound(ToNumber(a))
|
| + Node* input = ToNumber(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->NumberRound(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| @@ -242,9 +274,10 @@ Reduction JSBuiltinReducer::ReduceMathRound(Node* node) {
|
| // ES6 section 20.2.2.32 Math.sqrt ( x )
|
| 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());
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.sqrt(a:plain-primitive) -> NumberSqrt(ToNumber(a))
|
| + Node* input = ToNumber(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->NumberSqrt(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| @@ -253,9 +286,10 @@ Reduction JSBuiltinReducer::ReduceMathSqrt(Node* node) {
|
| // ES6 section 20.2.2.35 Math.trunc ( x )
|
| Reduction JSBuiltinReducer::ReduceMathTrunc(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchOne(Type::Number())) {
|
| - // Math.trunc(a:number) -> NumberTrunc(a)
|
| - Node* value = graph()->NewNode(simplified()->NumberTrunc(), r.left());
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // Math.trunc(a:plain-primitive) -> NumberTrunc(ToNumber(a))
|
| + Node* input = ToNumber(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->NumberTrunc(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| @@ -264,10 +298,10 @@ Reduction JSBuiltinReducer::ReduceMathTrunc(Node* node) {
|
| // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits )
|
| Reduction JSBuiltinReducer::ReduceStringFromCharCode(Node* node) {
|
| JSCallReduction r(node);
|
| - if (r.InputsMatchOne(Type::Number())) {
|
| - // String.fromCharCode(a:number) -> StringFromCharCode(a)
|
| - Node* value =
|
| - graph()->NewNode(simplified()->StringFromCharCode(), r.left());
|
| + if (r.InputsMatchOne(Type::PlainPrimitive())) {
|
| + // String.fromCharCode(a:plain-primitive) -> StringFromCharCode(a)
|
| + Node* input = ToNumber(r.GetJSCallInput(0));
|
| + Node* value = graph()->NewNode(simplified()->StringFromCharCode(), input);
|
| return Replace(value);
|
| }
|
| return NoChange();
|
| @@ -280,11 +314,11 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
|
| // Dispatch according to the BuiltinFunctionId if present.
|
| if (!r.HasBuiltinFunctionId()) return NoChange();
|
| switch (r.GetBuiltinFunctionId()) {
|
| - case kMathMax:
|
| - reduction = ReduceMathMax(node);
|
| + case kMathAtan:
|
| + reduction = ReduceMathAtan(node);
|
| break;
|
| - case kMathImul:
|
| - reduction = ReduceMathImul(node);
|
| + case kMathAtan2:
|
| + reduction = ReduceMathAtan2(node);
|
| break;
|
| case kMathClz32:
|
| reduction = ReduceMathClz32(node);
|
| @@ -298,11 +332,8 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
|
| case kMathFround:
|
| reduction = ReduceMathFround(node);
|
| break;
|
| - case kMathAtan:
|
| - reduction = ReduceMathAtan(node);
|
| - break;
|
| - case kMathAtan2:
|
| - reduction = ReduceMathAtan2(node);
|
| + case kMathImul:
|
| + reduction = ReduceMathImul(node);
|
| break;
|
| case kMathLog:
|
| reduction = ReduceMathLog(node);
|
| @@ -310,6 +341,12 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
|
| case kMathLog1p:
|
| reduction = ReduceMathLog1p(node);
|
| break;
|
| + case kMathMax:
|
| + reduction = ReduceMathMax(node);
|
| + break;
|
| + case kMathMin:
|
| + reduction = ReduceMathMin(node);
|
| + break;
|
| case kMathRound:
|
| reduction = ReduceMathRound(node);
|
| break;
|
| @@ -333,6 +370,18 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
|
| return reduction;
|
| }
|
|
|
| +Node* JSBuiltinReducer::ToNumber(Node* input) {
|
| + Type* input_type = NodeProperties::GetType(input);
|
| + if (input_type->Is(Type::Number())) return input;
|
| + return graph()->NewNode(simplified()->PlainPrimitiveToNumber(), input);
|
| +}
|
| +
|
| +Node* JSBuiltinReducer::ToUint32(Node* input) {
|
| + input = ToNumber(input);
|
| + Type* input_type = NodeProperties::GetType(input);
|
| + if (input_type->Is(Type::Unsigned32())) return input;
|
| + return graph()->NewNode(simplified()->NumberToUint32(), input);
|
| +}
|
|
|
| Graph* JSBuiltinReducer::graph() const { return jsgraph()->graph(); }
|
|
|
| @@ -345,11 +394,6 @@ CommonOperatorBuilder* JSBuiltinReducer::common() const {
|
| }
|
|
|
|
|
| -MachineOperatorBuilder* JSBuiltinReducer::machine() const {
|
| - return jsgraph()->machine();
|
| -}
|
| -
|
| -
|
| SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const {
|
| return jsgraph()->simplified();
|
| }
|
|
|