blob: 81d63924e1c4db8e0e63efa779a3def1d536c82f [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/compiler/js-builtin-reducer.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006#include "src/compiler/js-graph.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/compiler/node-matchers.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/compiler/node-properties.h"
9#include "src/compiler/simplified-operator.h"
10#include "src/objects-inl.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010011#include "src/type-cache.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012#include "src/types.h"
13
14namespace v8 {
15namespace internal {
16namespace compiler {
17
18
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019// Helper class to access JSCallFunction nodes that are potential candidates
20// for reduction when they have a BuiltinFunctionId associated with them.
21class JSCallReduction {
22 public:
23 explicit JSCallReduction(Node* node) : node_(node) {}
24
25 // Determines whether the node is a JSCallFunction operation that targets a
26 // constant callee being a well-known builtin with a BuiltinFunctionId.
27 bool HasBuiltinFunctionId() {
28 if (node_->opcode() != IrOpcode::kJSCallFunction) return false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000029 HeapObjectMatcher m(NodeProperties::GetValueInput(node_, 0));
30 if (!m.HasValue() || !m.Value()->IsJSFunction()) return false;
31 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032 return function->shared()->HasBuiltinFunctionId();
33 }
34
35 // Retrieves the BuiltinFunctionId as described above.
36 BuiltinFunctionId GetBuiltinFunctionId() {
37 DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 HeapObjectMatcher m(NodeProperties::GetValueInput(node_, 0));
39 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040 return function->shared()->builtin_function_id();
41 }
42
43 // Determines whether the call takes zero inputs.
44 bool InputsMatchZero() { return GetJSCallArity() == 0; }
45
46 // Determines whether the call takes one input of the given type.
47 bool InputsMatchOne(Type* t1) {
48 return GetJSCallArity() == 1 &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000049 NodeProperties::GetType(GetJSCallInput(0))->Is(t1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000050 }
51
52 // Determines whether the call takes two inputs of the given types.
53 bool InputsMatchTwo(Type* t1, Type* t2) {
54 return GetJSCallArity() == 2 &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000055 NodeProperties::GetType(GetJSCallInput(0))->Is(t1) &&
56 NodeProperties::GetType(GetJSCallInput(1))->Is(t2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000057 }
58
59 // Determines whether the call takes inputs all of the given type.
60 bool InputsMatchAll(Type* t) {
61 for (int i = 0; i < GetJSCallArity(); i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062 if (!NodeProperties::GetType(GetJSCallInput(i))->Is(t)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063 return false;
64 }
65 }
66 return true;
67 }
68
69 Node* left() { return GetJSCallInput(0); }
70 Node* right() { return GetJSCallInput(1); }
71
72 int GetJSCallArity() {
73 DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode());
74 // Skip first (i.e. callee) and second (i.e. receiver) operand.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040075 return node_->op()->ValueInputCount() - 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076 }
77
78 Node* GetJSCallInput(int index) {
79 DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode());
80 DCHECK_LT(index, GetJSCallArity());
81 // Skip first (i.e. callee) and second (i.e. receiver) operand.
82 return NodeProperties::GetValueInput(node_, index + 2);
83 }
84
85 private:
86 Node* node_;
87};
88
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089JSBuiltinReducer::JSBuiltinReducer(Editor* editor, JSGraph* jsgraph)
Ben Murdoch097c5b22016-05-18 11:27:45 +010090 : AdvancedReducer(editor),
91 jsgraph_(jsgraph),
92 type_cache_(TypeCache::Get()) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000093
Ben Murdoch61f157c2016-09-16 13:49:30 +010094// ES6 section 20.2.2.1 Math.abs ( x )
95Reduction JSBuiltinReducer::ReduceMathAbs(Node* node) {
96 JSCallReduction r(node);
97 if (r.InputsMatchOne(Type::PlainPrimitive())) {
98 // Math.abs(a:plain-primitive) -> NumberAbs(ToNumber(a))
99 Node* input = ToNumber(r.GetJSCallInput(0));
100 Node* value = graph()->NewNode(simplified()->NumberAbs(), input);
101 return Replace(value);
102 }
103 return NoChange();
104}
105
106// ES6 section 20.2.2.6 Math.atan ( x )
107Reduction JSBuiltinReducer::ReduceMathAtan(Node* node) {
108 JSCallReduction r(node);
109 if (r.InputsMatchOne(Type::PlainPrimitive())) {
110 // Math.atan(a:plain-primitive) -> NumberAtan(ToNumber(a))
111 Node* input = ToNumber(r.GetJSCallInput(0));
112 Node* value = graph()->NewNode(simplified()->NumberAtan(), input);
113 return Replace(value);
114 }
115 return NoChange();
116}
117
118// ES6 section 20.2.2.8 Math.atan2 ( y, x )
119Reduction JSBuiltinReducer::ReduceMathAtan2(Node* node) {
120 JSCallReduction r(node);
121 if (r.InputsMatchTwo(Type::PlainPrimitive(), Type::PlainPrimitive())) {
122 // Math.atan2(a:plain-primitive,
123 // b:plain-primitive) -> NumberAtan2(ToNumber(a),
124 // ToNumber(b))
125 Node* left = ToNumber(r.left());
126 Node* right = ToNumber(r.right());
127 Node* value = graph()->NewNode(simplified()->NumberAtan2(), left, right);
128 return Replace(value);
129 }
130 return NoChange();
131}
132
133// ES6 section 20.2.2.7 Math.atanh ( x )
134Reduction JSBuiltinReducer::ReduceMathAtanh(Node* node) {
135 JSCallReduction r(node);
136 if (r.InputsMatchOne(Type::Number())) {
137 // Math.atanh(a:number) -> NumberAtanh(a)
138 Node* value = graph()->NewNode(simplified()->NumberAtanh(), r.left());
139 return Replace(value);
140 }
141 return NoChange();
142}
143
144// ES6 section 20.2.2.10 Math.ceil ( x )
145Reduction JSBuiltinReducer::ReduceMathCeil(Node* node) {
146 JSCallReduction r(node);
147 if (r.InputsMatchOne(Type::PlainPrimitive())) {
148 // Math.ceil(a:plain-primitive) -> NumberCeil(ToNumber(a))
149 Node* input = ToNumber(r.GetJSCallInput(0));
150 Node* value = graph()->NewNode(simplified()->NumberCeil(), input);
151 return Replace(value);
152 }
153 return NoChange();
154}
155
156// ES6 section 20.2.2.11 Math.clz32 ( x )
157Reduction JSBuiltinReducer::ReduceMathClz32(Node* node) {
158 JSCallReduction r(node);
159 if (r.InputsMatchOne(Type::PlainPrimitive())) {
160 // Math.clz32(a:plain-primitive) -> NumberClz32(ToUint32(a))
161 Node* input = ToUint32(r.GetJSCallInput(0));
162 Node* value = graph()->NewNode(simplified()->NumberClz32(), input);
163 return Replace(value);
164 }
165 return NoChange();
166}
167
168// ES6 section 20.2.2.12 Math.cos ( x )
169Reduction JSBuiltinReducer::ReduceMathCos(Node* node) {
170 JSCallReduction r(node);
171 if (r.InputsMatchOne(Type::PlainPrimitive())) {
172 // Math.cos(a:plain-primitive) -> NumberCos(ToNumber(a))
173 Node* input = ToNumber(r.GetJSCallInput(0));
174 Node* value = graph()->NewNode(simplified()->NumberCos(), input);
175 return Replace(value);
176 }
177 return NoChange();
178}
179
180// ES6 section 20.2.2.14 Math.exp ( x )
181Reduction JSBuiltinReducer::ReduceMathExp(Node* node) {
182 JSCallReduction r(node);
183 if (r.InputsMatchOne(Type::PlainPrimitive())) {
184 // Math.exp(a:plain-primitive) -> NumberExp(ToNumber(a))
185 Node* input = ToNumber(r.GetJSCallInput(0));
186 Node* value = graph()->NewNode(simplified()->NumberExp(), input);
187 return Replace(value);
188 }
189 return NoChange();
190}
191
192// ES6 section 20.2.2.15 Math.expm1 ( x )
193Reduction JSBuiltinReducer::ReduceMathExpm1(Node* node) {
194 JSCallReduction r(node);
195 if (r.InputsMatchOne(Type::Number())) {
196 // Math.expm1(a:number) -> NumberExpm1(a)
197 Node* value = graph()->NewNode(simplified()->NumberExpm1(), r.left());
198 return Replace(value);
199 }
200 return NoChange();
201}
202
203// ES6 section 20.2.2.16 Math.floor ( x )
204Reduction JSBuiltinReducer::ReduceMathFloor(Node* node) {
205 JSCallReduction r(node);
206 if (r.InputsMatchOne(Type::PlainPrimitive())) {
207 // Math.floor(a:plain-primitive) -> NumberFloor(ToNumber(a))
208 Node* input = ToNumber(r.GetJSCallInput(0));
209 Node* value = graph()->NewNode(simplified()->NumberFloor(), input);
210 return Replace(value);
211 }
212 return NoChange();
213}
214
215// ES6 section 20.2.2.17 Math.fround ( x )
216Reduction JSBuiltinReducer::ReduceMathFround(Node* node) {
217 JSCallReduction r(node);
218 if (r.InputsMatchOne(Type::PlainPrimitive())) {
219 // Math.fround(a:plain-primitive) -> NumberFround(ToNumber(a))
220 Node* input = ToNumber(r.GetJSCallInput(0));
221 Node* value = graph()->NewNode(simplified()->NumberFround(), input);
222 return Replace(value);
223 }
224 return NoChange();
225}
226
227// ES6 section 20.2.2.19 Math.imul ( x, y )
228Reduction JSBuiltinReducer::ReduceMathImul(Node* node) {
229 JSCallReduction r(node);
230 if (r.InputsMatchTwo(Type::PlainPrimitive(), Type::PlainPrimitive())) {
231 // Math.imul(a:plain-primitive,
232 // b:plain-primitive) -> NumberImul(ToUint32(a),
233 // ToUint32(b))
234 Node* left = ToUint32(r.left());
235 Node* right = ToUint32(r.right());
236 Node* value = graph()->NewNode(simplified()->NumberImul(), left, right);
237 return Replace(value);
238 }
239 return NoChange();
240}
241
242// ES6 section 20.2.2.20 Math.log ( x )
243Reduction JSBuiltinReducer::ReduceMathLog(Node* node) {
244 JSCallReduction r(node);
245 if (r.InputsMatchOne(Type::PlainPrimitive())) {
246 // Math.log(a:plain-primitive) -> NumberLog(ToNumber(a))
247 Node* input = ToNumber(r.GetJSCallInput(0));
248 Node* value = graph()->NewNode(simplified()->NumberLog(), input);
249 return Replace(value);
250 }
251 return NoChange();
252}
253
254// ES6 section 20.2.2.21 Math.log1p ( x )
255Reduction JSBuiltinReducer::ReduceMathLog1p(Node* node) {
256 JSCallReduction r(node);
257 if (r.InputsMatchOne(Type::PlainPrimitive())) {
258 // Math.log1p(a:plain-primitive) -> NumberLog1p(ToNumber(a))
259 Node* input = ToNumber(r.GetJSCallInput(0));
260 Node* value = graph()->NewNode(simplified()->NumberLog1p(), input);
261 return Replace(value);
262 }
263 return NoChange();
264}
265
266// ES6 section 20.2.2.22 Math.log10 ( x )
267Reduction JSBuiltinReducer::ReduceMathLog10(Node* node) {
268 JSCallReduction r(node);
269 if (r.InputsMatchOne(Type::Number())) {
270 // Math.log10(a:number) -> NumberLog10(a)
271 Node* value = graph()->NewNode(simplified()->NumberLog10(), r.left());
272 return Replace(value);
273 }
274 return NoChange();
275}
276
277// ES6 section 20.2.2.23 Math.log2 ( x )
278Reduction JSBuiltinReducer::ReduceMathLog2(Node* node) {
279 JSCallReduction r(node);
280 if (r.InputsMatchOne(Type::Number())) {
281 // Math.log2(a:number) -> NumberLog(a)
282 Node* value = graph()->NewNode(simplified()->NumberLog2(), r.left());
283 return Replace(value);
284 }
285 return NoChange();
286}
287
288// ES6 section 20.2.2.24 Math.max ( value1, value2, ...values )
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000289Reduction JSBuiltinReducer::ReduceMathMax(Node* node) {
290 JSCallReduction r(node);
291 if (r.InputsMatchZero()) {
292 // Math.max() -> -Infinity
293 return Replace(jsgraph()->Constant(-V8_INFINITY));
294 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100295 if (r.InputsMatchOne(Type::PlainPrimitive())) {
296 // Math.max(a:plain-primitive) -> ToNumber(a)
297 Node* value = ToNumber(r.GetJSCallInput(0));
298 return Replace(value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000299 }
300 if (r.InputsMatchAll(Type::Integral32())) {
301 // Math.max(a:int32, b:int32, ...)
302 Node* value = r.GetJSCallInput(0);
303 for (int i = 1; i < r.GetJSCallArity(); i++) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400304 Node* const input = r.GetJSCallInput(i);
305 value = graph()->NewNode(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000306 common()->Select(MachineRepresentation::kNone),
307 graph()->NewNode(simplified()->NumberLessThan(), input, value), value,
308 input);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000309 }
310 return Replace(value);
311 }
312 return NoChange();
313}
314
Ben Murdoch61f157c2016-09-16 13:49:30 +0100315// ES6 section 20.2.2.25 Math.min ( value1, value2, ...values )
316Reduction JSBuiltinReducer::ReduceMathMin(Node* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000317 JSCallReduction r(node);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100318 if (r.InputsMatchZero()) {
319 // Math.min() -> Infinity
320 return Replace(jsgraph()->Constant(V8_INFINITY));
321 }
322 if (r.InputsMatchOne(Type::PlainPrimitive())) {
323 // Math.min(a:plain-primitive) -> ToNumber(a)
324 Node* value = ToNumber(r.GetJSCallInput(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000325 return Replace(value);
326 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100327 if (r.InputsMatchAll(Type::Integral32())) {
328 // Math.min(a:int32, b:int32, ...)
329 Node* value = r.GetJSCallInput(0);
330 for (int i = 1; i < r.GetJSCallArity(); i++) {
331 Node* const input = r.GetJSCallInput(i);
332 value = graph()->NewNode(
333 common()->Select(MachineRepresentation::kNone),
334 graph()->NewNode(simplified()->NumberLessThan(), input, value), input,
335 value);
336 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400337 return Replace(value);
338 }
339 return NoChange();
340}
341
Ben Murdoch097c5b22016-05-18 11:27:45 +0100342// ES6 section 20.2.2.28 Math.round ( x )
343Reduction JSBuiltinReducer::ReduceMathRound(Node* node) {
344 JSCallReduction r(node);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100345 if (r.InputsMatchOne(Type::PlainPrimitive())) {
346 // Math.round(a:plain-primitive) -> NumberRound(ToNumber(a))
347 Node* input = ToNumber(r.GetJSCallInput(0));
348 Node* value = graph()->NewNode(simplified()->NumberRound(), input);
349 return Replace(value);
350 }
351 return NoChange();
352}
353
354// ES6 section 20.2.2.9 Math.cbrt ( x )
355Reduction JSBuiltinReducer::ReduceMathCbrt(Node* node) {
356 JSCallReduction r(node);
Ben Murdochda12d292016-06-02 14:46:10 +0100357 if (r.InputsMatchOne(Type::Number())) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100358 // Math.cbrt(a:number) -> NumberCbrt(a)
359 Node* value = graph()->NewNode(simplified()->NumberCbrt(), r.left());
360 return Replace(value);
361 }
362 return NoChange();
363}
364
365// ES6 section 20.2.2.30 Math.sin ( x )
366Reduction JSBuiltinReducer::ReduceMathSin(Node* node) {
367 JSCallReduction r(node);
368 if (r.InputsMatchOne(Type::PlainPrimitive())) {
369 // Math.sin(a:plain-primitive) -> NumberSin(ToNumber(a))
370 Node* input = ToNumber(r.GetJSCallInput(0));
371 Node* value = graph()->NewNode(simplified()->NumberSin(), input);
Ben Murdochda12d292016-06-02 14:46:10 +0100372 return Replace(value);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100373 }
Ben Murdochda12d292016-06-02 14:46:10 +0100374 return NoChange();
375}
376
377// ES6 section 20.2.2.32 Math.sqrt ( x )
378Reduction JSBuiltinReducer::ReduceMathSqrt(Node* node) {
379 JSCallReduction r(node);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100380 if (r.InputsMatchOne(Type::PlainPrimitive())) {
381 // Math.sqrt(a:plain-primitive) -> NumberSqrt(ToNumber(a))
382 Node* input = ToNumber(r.GetJSCallInput(0));
383 Node* value = graph()->NewNode(simplified()->NumberSqrt(), input);
384 return Replace(value);
385 }
386 return NoChange();
387}
388
389// ES6 section 20.2.2.33 Math.tan ( x )
390Reduction JSBuiltinReducer::ReduceMathTan(Node* node) {
391 JSCallReduction r(node);
392 if (r.InputsMatchOne(Type::PlainPrimitive())) {
393 // Math.tan(a:plain-primitive) -> NumberTan(ToNumber(a))
394 Node* input = ToNumber(r.GetJSCallInput(0));
395 Node* value = graph()->NewNode(simplified()->NumberTan(), input);
Ben Murdochda12d292016-06-02 14:46:10 +0100396 return Replace(value);
397 }
398 return NoChange();
399}
400
401// ES6 section 20.2.2.35 Math.trunc ( x )
402Reduction JSBuiltinReducer::ReduceMathTrunc(Node* node) {
403 JSCallReduction r(node);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100404 if (r.InputsMatchOne(Type::PlainPrimitive())) {
405 // Math.trunc(a:plain-primitive) -> NumberTrunc(ToNumber(a))
406 Node* input = ToNumber(r.GetJSCallInput(0));
407 Node* value = graph()->NewNode(simplified()->NumberTrunc(), input);
408 return Replace(value);
409 }
410 return NoChange();
411}
412
413// ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits )
414Reduction JSBuiltinReducer::ReduceStringFromCharCode(Node* node) {
415 JSCallReduction r(node);
416 if (r.InputsMatchOne(Type::PlainPrimitive())) {
417 // String.fromCharCode(a:plain-primitive) -> StringFromCharCode(a)
418 Node* input = ToNumber(r.GetJSCallInput(0));
419 Node* value = graph()->NewNode(simplified()->StringFromCharCode(), input);
Ben Murdochda12d292016-06-02 14:46:10 +0100420 return Replace(value);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100421 }
422 return NoChange();
423}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400424
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000425Reduction JSBuiltinReducer::Reduce(Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000426 Reduction reduction = NoChange();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000427 JSCallReduction r(node);
428
429 // Dispatch according to the BuiltinFunctionId if present.
430 if (!r.HasBuiltinFunctionId()) return NoChange();
431 switch (r.GetBuiltinFunctionId()) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100432 case kMathAbs:
433 reduction = ReduceMathAbs(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000434 break;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100435 case kMathAtan:
436 reduction = ReduceMathAtan(node);
437 break;
438 case kMathAtan2:
439 reduction = ReduceMathAtan2(node);
440 break;
441 case kMathAtanh:
442 reduction = ReduceMathAtanh(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000443 break;
Ben Murdochda12d292016-06-02 14:46:10 +0100444 case kMathClz32:
445 reduction = ReduceMathClz32(node);
446 break;
447 case kMathCeil:
448 reduction = ReduceMathCeil(node);
449 break;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100450 case kMathCos:
451 reduction = ReduceMathCos(node);
452 break;
453 case kMathExp:
454 reduction = ReduceMathExp(node);
455 break;
456 case kMathExpm1:
457 reduction = ReduceMathExpm1(node);
458 break;
Ben Murdochda12d292016-06-02 14:46:10 +0100459 case kMathFloor:
460 reduction = ReduceMathFloor(node);
461 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400462 case kMathFround:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000463 reduction = ReduceMathFround(node);
464 break;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100465 case kMathImul:
466 reduction = ReduceMathImul(node);
467 break;
468 case kMathLog:
469 reduction = ReduceMathLog(node);
470 break;
471 case kMathLog1p:
472 reduction = ReduceMathLog1p(node);
473 break;
474 case kMathLog10:
475 reduction = ReduceMathLog10(node);
476 break;
477 case kMathLog2:
478 reduction = ReduceMathLog2(node);
479 break;
480 case kMathMax:
481 reduction = ReduceMathMax(node);
482 break;
483 case kMathMin:
484 reduction = ReduceMathMin(node);
485 break;
486 case kMathCbrt:
487 reduction = ReduceMathCbrt(node);
488 break;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100489 case kMathRound:
490 reduction = ReduceMathRound(node);
491 break;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100492 case kMathSin:
493 reduction = ReduceMathSin(node);
494 break;
Ben Murdochda12d292016-06-02 14:46:10 +0100495 case kMathSqrt:
496 reduction = ReduceMathSqrt(node);
497 break;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100498 case kMathTan:
499 reduction = ReduceMathTan(node);
500 break;
Ben Murdochda12d292016-06-02 14:46:10 +0100501 case kMathTrunc:
502 reduction = ReduceMathTrunc(node);
503 break;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100504 case kStringFromCharCode:
505 reduction = ReduceStringFromCharCode(node);
506 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000507 default:
508 break;
509 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000510
511 // Replace builtin call assuming replacement nodes are pure values that don't
512 // produce an effect. Replaces {node} with {reduction} and relaxes effects.
513 if (reduction.Changed()) ReplaceWithValue(node, reduction.replacement());
514
515 return reduction;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000516}
517
Ben Murdoch61f157c2016-09-16 13:49:30 +0100518Node* JSBuiltinReducer::ToNumber(Node* input) {
519 Type* input_type = NodeProperties::GetType(input);
520 if (input_type->Is(Type::Number())) return input;
521 return graph()->NewNode(simplified()->PlainPrimitiveToNumber(), input);
522}
523
524Node* JSBuiltinReducer::ToUint32(Node* input) {
525 input = ToNumber(input);
526 Type* input_type = NodeProperties::GetType(input);
527 if (input_type->Is(Type::Unsigned32())) return input;
528 return graph()->NewNode(simplified()->NumberToUint32(), input);
529}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400530
531Graph* JSBuiltinReducer::graph() const { return jsgraph()->graph(); }
532
533
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000534Isolate* JSBuiltinReducer::isolate() const { return jsgraph()->isolate(); }
535
536
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400537CommonOperatorBuilder* JSBuiltinReducer::common() const {
538 return jsgraph()->common();
539}
540
541
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000542SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const {
543 return jsgraph()->simplified();
544}
545
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000546} // namespace compiler
547} // namespace internal
548} // namespace v8