[runtime] Remove useless IN builtin.
[platform/upstream/v8.git] / src / compiler / js-intrinsic-lowering.cc
1 // Copyright 2015 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
5 #include "src/compiler/js-intrinsic-lowering.h"
6
7 #include <stack>
8
9 #include "src/compiler/access-builder.h"
10 #include "src/compiler/js-graph.h"
11 #include "src/compiler/node-matchers.h"
12 #include "src/compiler/node-properties.h"
13 #include "src/compiler/operator-properties.h"
14
15 namespace v8 {
16 namespace internal {
17 namespace compiler {
18
19 JSIntrinsicLowering::JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph,
20                                          DeoptimizationMode mode)
21     : AdvancedReducer(editor),
22       jsgraph_(jsgraph),
23       mode_(mode),
24       simplified_(jsgraph->zone()) {}
25
26
27 Reduction JSIntrinsicLowering::Reduce(Node* node) {
28   if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange();
29   const Runtime::Function* const f =
30       Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id());
31   if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange();
32   switch (f->function_id) {
33     case Runtime::kInlineConstructDouble:
34       return ReduceConstructDouble(node);
35     case Runtime::kInlineDateField:
36       return ReduceDateField(node);
37     case Runtime::kInlineDeoptimizeNow:
38       return ReduceDeoptimizeNow(node);
39     case Runtime::kInlineDoubleHi:
40       return ReduceDoubleHi(node);
41     case Runtime::kInlineDoubleLo:
42       return ReduceDoubleLo(node);
43     case Runtime::kInlineHeapObjectGetMap:
44       return ReduceHeapObjectGetMap(node);
45     case Runtime::kInlineIncrementStatsCounter:
46       return ReduceIncrementStatsCounter(node);
47     case Runtime::kInlineIsArray:
48       return ReduceIsInstanceType(node, JS_ARRAY_TYPE);
49     case Runtime::kInlineIsDate:
50       return ReduceIsInstanceType(node, JS_DATE_TYPE);
51     case Runtime::kInlineIsTypedArray:
52       return ReduceIsInstanceType(node, JS_TYPED_ARRAY_TYPE);
53     case Runtime::kInlineIsFunction:
54       return ReduceIsInstanceType(node, JS_FUNCTION_TYPE);
55     case Runtime::kInlineIsRegExp:
56       return ReduceIsInstanceType(node, JS_REGEXP_TYPE);
57     case Runtime::kInlineIsSmi:
58       return ReduceIsSmi(node);
59     case Runtime::kInlineJSValueGetValue:
60       return ReduceJSValueGetValue(node);
61     case Runtime::kInlineLikely:
62       return ReduceUnLikely(node, BranchHint::kTrue);
63     case Runtime::kInlineMapGetInstanceType:
64       return ReduceMapGetInstanceType(node);
65     case Runtime::kInlineMathClz32:
66       return ReduceMathClz32(node);
67     case Runtime::kInlineMathFloor:
68       return ReduceMathFloor(node);
69     case Runtime::kInlineMathSqrt:
70       return ReduceMathSqrt(node);
71     case Runtime::kInlineOneByteSeqStringGetChar:
72       return ReduceSeqStringGetChar(node, String::ONE_BYTE_ENCODING);
73     case Runtime::kInlineOneByteSeqStringSetChar:
74       return ReduceSeqStringSetChar(node, String::ONE_BYTE_ENCODING);
75     case Runtime::kInlineStringGetLength:
76       return ReduceStringGetLength(node);
77     case Runtime::kInlineTwoByteSeqStringGetChar:
78       return ReduceSeqStringGetChar(node, String::TWO_BYTE_ENCODING);
79     case Runtime::kInlineTwoByteSeqStringSetChar:
80       return ReduceSeqStringSetChar(node, String::TWO_BYTE_ENCODING);
81     case Runtime::kInlineUnlikely:
82       return ReduceUnLikely(node, BranchHint::kFalse);
83     case Runtime::kInlineValueOf:
84       return ReduceValueOf(node);
85     case Runtime::kInlineIsMinusZero:
86       return ReduceIsMinusZero(node);
87     case Runtime::kInlineFixedArrayGet:
88       return ReduceFixedArrayGet(node);
89     case Runtime::kInlineFixedArraySet:
90       return ReduceFixedArraySet(node);
91     case Runtime::kInlineGetTypeFeedbackVector:
92       return ReduceGetTypeFeedbackVector(node);
93     case Runtime::kInlineGetCallerJSFunction:
94       return ReduceGetCallerJSFunction(node);
95     case Runtime::kInlineToObject:
96       return ReduceToObject(node);
97     case Runtime::kInlineThrowNotDateError:
98       return ReduceThrowNotDateError(node);
99     case Runtime::kInlineCallFunction:
100       return ReduceCallFunction(node);
101     default:
102       break;
103   }
104   return NoChange();
105 }
106
107
108 Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) {
109   Node* high = NodeProperties::GetValueInput(node, 0);
110   Node* low = NodeProperties::GetValueInput(node, 1);
111   Node* value =
112       graph()->NewNode(machine()->Float64InsertHighWord32(),
113                        graph()->NewNode(machine()->Float64InsertLowWord32(),
114                                         jsgraph()->Constant(0), low),
115                        high);
116   ReplaceWithValue(node, value);
117   return Replace(value);
118 }
119
120
121 Reduction JSIntrinsicLowering::ReduceDateField(Node* node) {
122   Node* const value = NodeProperties::GetValueInput(node, 0);
123   Node* const index = NodeProperties::GetValueInput(node, 1);
124   Node* const effect = NodeProperties::GetEffectInput(node);
125   Node* const control = NodeProperties::GetControlInput(node);
126   NumberMatcher mindex(index);
127   if (mindex.Is(JSDate::kDateValue)) {
128     return Change(
129         node,
130         simplified()->LoadField(AccessBuilder::ForJSDateField(
131             static_cast<JSDate::FieldIndex>(static_cast<int>(mindex.Value())))),
132         value, effect, control);
133   }
134   // TODO(turbofan): Optimize more patterns.
135   return NoChange();
136 }
137
138
139 Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
140   if (mode() != kDeoptimizationEnabled) return NoChange();
141   Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
142   Node* const effect = NodeProperties::GetEffectInput(node);
143   Node* const control = NodeProperties::GetControlInput(node);
144
145   // TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
146   Node* deoptimize =
147       graph()->NewNode(common()->Deoptimize(), frame_state, effect, control);
148   NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
149
150   node->set_op(common()->Dead());
151   node->TrimInputCount(0);
152   return Changed(node);
153 }
154
155
156 Reduction JSIntrinsicLowering::ReduceDoubleHi(Node* node) {
157   return Change(node, machine()->Float64ExtractHighWord32());
158 }
159
160
161 Reduction JSIntrinsicLowering::ReduceDoubleLo(Node* node) {
162   return Change(node, machine()->Float64ExtractLowWord32());
163 }
164
165
166 Reduction JSIntrinsicLowering::ReduceHeapObjectGetMap(Node* node) {
167   Node* value = NodeProperties::GetValueInput(node, 0);
168   Node* effect = NodeProperties::GetEffectInput(node);
169   Node* control = NodeProperties::GetControlInput(node);
170   return Change(node, simplified()->LoadField(AccessBuilder::ForMap()), value,
171                 effect, control);
172 }
173
174
175 Reduction JSIntrinsicLowering::ReduceIncrementStatsCounter(Node* node) {
176   if (!FLAG_native_code_counters) return ChangeToUndefined(node);
177   HeapObjectMatcher m(NodeProperties::GetValueInput(node, 0));
178   if (!m.HasValue() || !m.Value().handle()->IsString()) {
179     return ChangeToUndefined(node);
180   }
181   base::SmartArrayPointer<char> name =
182       Handle<String>::cast(m.Value().handle())->ToCString();
183   StatsCounter counter(jsgraph()->isolate(), name.get());
184   if (!counter.Enabled()) return ChangeToUndefined(node);
185
186   Node* effect = NodeProperties::GetEffectInput(node);
187   Node* control = NodeProperties::GetControlInput(node);
188   FieldAccess access = AccessBuilder::ForStatsCounter();
189   Node* cnt = jsgraph()->ExternalConstant(ExternalReference(&counter));
190   Node* load =
191       graph()->NewNode(simplified()->LoadField(access), cnt, effect, control);
192   Node* inc =
193       graph()->NewNode(machine()->Int32Add(), load, jsgraph()->OneConstant());
194   Node* store = graph()->NewNode(simplified()->StoreField(access), cnt, inc,
195                                  load, control);
196   return ChangeToUndefined(node, store);
197 }
198
199
200 Reduction JSIntrinsicLowering::ReduceIsInstanceType(
201     Node* node, InstanceType instance_type) {
202   // if (%_IsSmi(value)) {
203   //   return false;
204   // } else {
205   //   return %_GetInstanceType(%_GetMap(value)) == instance_type;
206   // }
207   MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged);
208
209   Node* value = NodeProperties::GetValueInput(node, 0);
210   Node* effect = NodeProperties::GetEffectInput(node);
211   Node* control = NodeProperties::GetControlInput(node);
212
213   Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
214   Node* branch = graph()->NewNode(common()->Branch(), check, control);
215
216   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
217   Node* etrue = effect;
218   Node* vtrue = jsgraph()->FalseConstant();
219
220   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
221   Node* efalse = graph()->NewNode(
222       simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
223       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), value,
224                        effect, if_false),
225       effect, if_false);
226   Node* vfalse = graph()->NewNode(machine()->Word32Equal(), efalse,
227                                   jsgraph()->Int32Constant(instance_type));
228
229   Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
230
231   // Replace all effect uses of {node} with the {ephi}.
232   Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
233   ReplaceWithValue(node, node, ephi);
234
235   // Turn the {node} into a Phi.
236   return Change(node, common()->Phi(type, 2), vtrue, vfalse, merge);
237 }
238
239
240 Reduction JSIntrinsicLowering::ReduceIsSmi(Node* node) {
241   return Change(node, simplified()->ObjectIsSmi());
242 }
243
244
245 Reduction JSIntrinsicLowering::ReduceJSValueGetValue(Node* node) {
246   Node* value = NodeProperties::GetValueInput(node, 0);
247   Node* effect = NodeProperties::GetEffectInput(node);
248   Node* control = NodeProperties::GetControlInput(node);
249   return Change(node, simplified()->LoadField(AccessBuilder::ForValue()), value,
250                 effect, control);
251 }
252
253
254 Reduction JSIntrinsicLowering::ReduceMapGetInstanceType(Node* node) {
255   Node* value = NodeProperties::GetValueInput(node, 0);
256   Node* effect = NodeProperties::GetEffectInput(node);
257   Node* control = NodeProperties::GetControlInput(node);
258   return Change(node,
259                 simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
260                 value, effect, control);
261 }
262
263
264 Reduction JSIntrinsicLowering::ReduceMathClz32(Node* node) {
265   return Change(node, machine()->Word32Clz());
266 }
267
268
269 Reduction JSIntrinsicLowering::ReduceMathFloor(Node* node) {
270   if (!machine()->Float64RoundDown().IsSupported()) return NoChange();
271   return Change(node, machine()->Float64RoundDown().op());
272 }
273
274
275 Reduction JSIntrinsicLowering::ReduceMathSqrt(Node* node) {
276   return Change(node, machine()->Float64Sqrt());
277 }
278
279
280 Reduction JSIntrinsicLowering::ReduceSeqStringGetChar(
281     Node* node, String::Encoding encoding) {
282   Node* effect = NodeProperties::GetEffectInput(node);
283   Node* control = NodeProperties::GetControlInput(node);
284   node->set_op(
285       simplified()->LoadElement(AccessBuilder::ForSeqStringChar(encoding)));
286   node->ReplaceInput(2, effect);
287   node->ReplaceInput(3, control);
288   node->TrimInputCount(4);
289   RelaxControls(node);
290   return Changed(node);
291 }
292
293
294 Reduction JSIntrinsicLowering::ReduceSeqStringSetChar(
295     Node* node, String::Encoding encoding) {
296   // Note: The intrinsic has a strange argument order, so we need to reshuffle.
297   Node* index = NodeProperties::GetValueInput(node, 0);
298   Node* chr = NodeProperties::GetValueInput(node, 1);
299   Node* string = NodeProperties::GetValueInput(node, 2);
300   Node* effect = NodeProperties::GetEffectInput(node);
301   Node* control = NodeProperties::GetControlInput(node);
302   node->set_op(
303       simplified()->StoreElement(AccessBuilder::ForSeqStringChar(encoding)));
304   node->ReplaceInput(0, string);
305   node->ReplaceInput(1, index);
306   node->ReplaceInput(2, chr);
307   node->ReplaceInput(3, effect);
308   node->ReplaceInput(4, control);
309   node->TrimInputCount(5);
310   NodeProperties::RemoveBounds(node);
311   ReplaceWithValue(node, string, node);
312   return Changed(node);
313 }
314
315
316 Reduction JSIntrinsicLowering::ReduceStringGetLength(Node* node) {
317   Node* value = NodeProperties::GetValueInput(node, 0);
318   Node* effect = NodeProperties::GetEffectInput(node);
319   Node* control = NodeProperties::GetControlInput(node);
320   return Change(node, simplified()->LoadField(
321                           AccessBuilder::ForStringLength(graph()->zone())),
322                 value, effect, control);
323 }
324
325
326 Reduction JSIntrinsicLowering::ReduceUnLikely(Node* node, BranchHint hint) {
327   std::stack<Node*> nodes_to_visit;
328   nodes_to_visit.push(node);
329   while (!nodes_to_visit.empty()) {
330     Node* current = nodes_to_visit.top();
331     nodes_to_visit.pop();
332     for (Node* use : current->uses()) {
333       if (use->opcode() == IrOpcode::kJSToBoolean) {
334         // We have to "look through" ToBoolean calls.
335         nodes_to_visit.push(use);
336       } else if (use->opcode() == IrOpcode::kBranch) {
337         // Actually set the hint on any branch using the intrinsic node.
338         use->set_op(common()->Branch(hint));
339       }
340     }
341   }
342   // Apart from adding hints to branchs nodes, this is the identity function.
343   Node* value = NodeProperties::GetValueInput(node, 0);
344   ReplaceWithValue(node, value);
345   return Changed(value);
346 }
347
348
349 Reduction JSIntrinsicLowering::ReduceValueOf(Node* node) {
350   // if (%_IsSmi(value)) {
351   //   return value;
352   // } else if (%_GetInstanceType(%_GetMap(value)) == JS_VALUE_TYPE) {
353   //   return %_GetValue(value);
354   // } else {
355   //   return value;
356   // }
357   const Operator* const merge_op = common()->Merge(2);
358   const Operator* const ephi_op = common()->EffectPhi(2);
359   const Operator* const phi_op = common()->Phi(kMachAnyTagged, 2);
360
361   Node* value = NodeProperties::GetValueInput(node, 0);
362   Node* effect = NodeProperties::GetEffectInput(node);
363   Node* control = NodeProperties::GetControlInput(node);
364
365   Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
366   Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
367
368   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
369   Node* etrue0 = effect;
370   Node* vtrue0 = value;
371
372   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
373   Node* efalse0;
374   Node* vfalse0;
375   {
376     Node* check1 = graph()->NewNode(
377         machine()->Word32Equal(),
378         graph()->NewNode(
379             simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
380             graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
381                              value, effect, if_false0),
382             effect, if_false0),
383         jsgraph()->Int32Constant(JS_VALUE_TYPE));
384     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
385
386     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
387     Node* etrue1 =
388         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForValue()),
389                          value, effect, if_true1);
390     Node* vtrue1 = etrue1;
391
392     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
393     Node* efalse1 = effect;
394     Node* vfalse1 = value;
395
396     Node* merge1 = graph()->NewNode(merge_op, if_true1, if_false1);
397     efalse0 = graph()->NewNode(ephi_op, etrue1, efalse1, merge1);
398     vfalse0 = graph()->NewNode(phi_op, vtrue1, vfalse1, merge1);
399   }
400
401   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
402
403   // Replace all effect uses of {node} with the {ephi0}.
404   Node* ephi0 = graph()->NewNode(ephi_op, etrue0, efalse0, merge0);
405   ReplaceWithValue(node, node, ephi0);
406
407   // Turn the {node} into a Phi.
408   return Change(node, phi_op, vtrue0, vfalse0, merge0);
409 }
410
411
412 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) {
413   // Replace all effect uses of {node} with the effect dependency.
414   RelaxEffectsAndControls(node);
415   // Remove the inputs corresponding to context, effect and control.
416   NodeProperties::RemoveNonValueInputs(node);
417   // Finally update the operator to the new one.
418   node->set_op(op);
419   return Changed(node);
420 }
421
422
423 Reduction JSIntrinsicLowering::ReduceIsMinusZero(Node* node) {
424   Node* value = NodeProperties::GetValueInput(node, 0);
425   Node* effect = NodeProperties::GetEffectInput(node);
426
427   Node* double_lo =
428       graph()->NewNode(machine()->Float64ExtractLowWord32(), value);
429   Node* check1 = graph()->NewNode(machine()->Word32Equal(), double_lo,
430                                   jsgraph()->ZeroConstant());
431
432   Node* double_hi =
433       graph()->NewNode(machine()->Float64ExtractHighWord32(), value);
434   Node* check2 = graph()->NewNode(
435       machine()->Word32Equal(), double_hi,
436       jsgraph()->Int32Constant(static_cast<int32_t>(0x80000000)));
437
438   ReplaceWithValue(node, node, effect);
439
440   Node* and_result = graph()->NewNode(machine()->Word32And(), check1, check2);
441
442   return Change(node, machine()->Word32Equal(), and_result,
443                 jsgraph()->Int32Constant(1));
444 }
445
446
447 Reduction JSIntrinsicLowering::ReduceFixedArrayGet(Node* node) {
448   Node* base = node->InputAt(0);
449   Node* index = node->InputAt(1);
450   Node* effect = NodeProperties::GetEffectInput(node);
451   Node* control = NodeProperties::GetControlInput(node);
452   return Change(
453       node, simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()),
454       base, index, effect, control);
455 }
456
457
458 Reduction JSIntrinsicLowering::ReduceFixedArraySet(Node* node) {
459   Node* base = node->InputAt(0);
460   Node* index = node->InputAt(1);
461   Node* value = node->InputAt(2);
462   Node* effect = NodeProperties::GetEffectInput(node);
463   Node* control = NodeProperties::GetControlInput(node);
464   Node* store = (graph()->NewNode(
465       simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()), base,
466       index, value, effect, control));
467   ReplaceWithValue(node, value, store);
468   return Changed(store);
469 }
470
471
472 Reduction JSIntrinsicLowering::ReduceGetTypeFeedbackVector(Node* node) {
473   Node* func = node->InputAt(0);
474   Node* effect = NodeProperties::GetEffectInput(node);
475   Node* control = NodeProperties::GetControlInput(node);
476   FieldAccess access = AccessBuilder::ForJSFunctionSharedFunctionInfo();
477   Node* load =
478       graph()->NewNode(simplified()->LoadField(access), func, effect, control);
479   access = AccessBuilder::ForSharedFunctionInfoTypeFeedbackVector();
480   return Change(node, simplified()->LoadField(access), load, load, control);
481 }
482
483
484 Reduction JSIntrinsicLowering::ReduceGetCallerJSFunction(Node* node) {
485   Node* effect = NodeProperties::GetEffectInput(node);
486   Node* control = NodeProperties::GetControlInput(node);
487
488   Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
489   Node* outer_frame = frame_state->InputAt(kFrameStateOuterStateInput);
490   if (outer_frame->opcode() == IrOpcode::kFrameState) {
491     // Use the runtime implementation to throw the appropriate error if the
492     // containing function is inlined.
493     return NoChange();
494   }
495
496   // TODO(danno): This implementation forces intrinsic lowering to happen after
497   // inlining, which is fine for now, but eventually the frame-querying logic
498   // probably should go later, e.g. in instruction selection, so that there is
499   // no phase-ordering dependency.
500   FieldAccess access = AccessBuilder::ForFrameCallerFramePtr();
501   Node* fp = graph()->NewNode(machine()->LoadFramePointer());
502   Node* next_fp =
503       graph()->NewNode(simplified()->LoadField(access), fp, effect, control);
504   return Change(node, simplified()->LoadField(AccessBuilder::ForFrameMarker()),
505                 next_fp, effect, control);
506 }
507
508
509 Reduction JSIntrinsicLowering::ReduceThrowNotDateError(Node* node) {
510   if (mode() != kDeoptimizationEnabled) return NoChange();
511   Node* const frame_state = NodeProperties::GetFrameStateInput(node, 1);
512   Node* const effect = NodeProperties::GetEffectInput(node);
513   Node* const control = NodeProperties::GetControlInput(node);
514
515   // TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
516   Node* deoptimize =
517       graph()->NewNode(common()->Deoptimize(), frame_state, effect, control);
518   NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
519
520   node->set_op(common()->Dead());
521   node->TrimInputCount(0);
522   return Changed(node);
523 }
524
525
526 Reduction JSIntrinsicLowering::ReduceToObject(Node* node) {
527   node->set_op(javascript()->ToObject());
528   return Changed(node);
529 }
530
531
532 Reduction JSIntrinsicLowering::ReduceCallFunction(Node* node) {
533   CallRuntimeParameters params = OpParameter<CallRuntimeParameters>(node->op());
534   size_t arity = params.arity();
535   node->set_op(javascript()->CallFunction(arity, NO_CALL_FUNCTION_FLAGS, STRICT,
536                                           VectorSlotPair(), ALLOW_TAIL_CALLS));
537   Node* function = node->InputAt(static_cast<int>(arity - 1));
538   while (--arity != 0) {
539     node->ReplaceInput(static_cast<int>(arity),
540                        node->InputAt(static_cast<int>(arity - 1)));
541   }
542   node->ReplaceInput(0, function);
543   return Changed(node);
544 }
545
546
547 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
548                                       Node* b) {
549   node->set_op(op);
550   node->ReplaceInput(0, a);
551   node->ReplaceInput(1, b);
552   node->TrimInputCount(2);
553   RelaxControls(node);
554   return Changed(node);
555 }
556
557
558 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
559                                       Node* b, Node* c) {
560   node->set_op(op);
561   node->ReplaceInput(0, a);
562   node->ReplaceInput(1, b);
563   node->ReplaceInput(2, c);
564   node->TrimInputCount(3);
565   RelaxControls(node);
566   return Changed(node);
567 }
568
569
570 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
571                                       Node* b, Node* c, Node* d) {
572   node->set_op(op);
573   node->ReplaceInput(0, a);
574   node->ReplaceInput(1, b);
575   node->ReplaceInput(2, c);
576   node->ReplaceInput(3, d);
577   node->TrimInputCount(4);
578   RelaxControls(node);
579   return Changed(node);
580 }
581
582
583 Reduction JSIntrinsicLowering::ChangeToUndefined(Node* node, Node* effect) {
584   ReplaceWithValue(node, jsgraph()->UndefinedConstant(), effect);
585   return Changed(node);
586 }
587
588
589 Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); }
590
591
592 CommonOperatorBuilder* JSIntrinsicLowering::common() const {
593   return jsgraph()->common();
594 }
595
596 JSOperatorBuilder* JSIntrinsicLowering::javascript() const {
597   return jsgraph_->javascript();
598 }
599
600
601 MachineOperatorBuilder* JSIntrinsicLowering::machine() const {
602   return jsgraph()->machine();
603 }
604
605 }  // namespace compiler
606 }  // namespace internal
607 }  // namespace v8