blob: abeb11001d6a5c8e408ab87e0d4f17dd87e2f7fc [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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/code-factory.h"
10#include "src/compiler/access-builder.h"
11#include "src/compiler/js-graph.h"
12#include "src/compiler/linkage.h"
13#include "src/compiler/node-matchers.h"
14#include "src/compiler/node-properties.h"
15#include "src/compiler/operator-properties.h"
16#include "src/counters.h"
17#include "src/objects-inl.h"
18#include "src/type-cache.h"
19
20namespace v8 {
21namespace internal {
22namespace compiler {
23
24JSIntrinsicLowering::JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph,
25 DeoptimizationMode mode)
26 : AdvancedReducer(editor),
27 jsgraph_(jsgraph),
28 mode_(mode),
29 type_cache_(TypeCache::Get()) {}
30
31
32Reduction JSIntrinsicLowering::Reduce(Node* node) {
33 if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange();
34 const Runtime::Function* const f =
35 Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id());
36 if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange();
37 switch (f->function_id) {
38 case Runtime::kInlineConstructDouble:
39 return ReduceConstructDouble(node);
40 case Runtime::kInlineCreateIterResultObject:
41 return ReduceCreateIterResultObject(node);
42 case Runtime::kInlineDeoptimizeNow:
43 return ReduceDeoptimizeNow(node);
44 case Runtime::kInlineDoubleHi:
45 return ReduceDoubleHi(node);
46 case Runtime::kInlineDoubleLo:
47 return ReduceDoubleLo(node);
48 case Runtime::kInlineIncrementStatsCounter:
49 return ReduceIncrementStatsCounter(node);
50 case Runtime::kInlineIsArray:
51 return ReduceIsInstanceType(node, JS_ARRAY_TYPE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052 case Runtime::kInlineIsTypedArray:
53 return ReduceIsInstanceType(node, JS_TYPED_ARRAY_TYPE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054 case Runtime::kInlineIsRegExp:
55 return ReduceIsInstanceType(node, JS_REGEXP_TYPE);
56 case Runtime::kInlineIsJSReceiver:
57 return ReduceIsJSReceiver(node);
58 case Runtime::kInlineIsSmi:
59 return ReduceIsSmi(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060 case Runtime::kInlineMathClz32:
61 return ReduceMathClz32(node);
62 case Runtime::kInlineMathFloor:
63 return ReduceMathFloor(node);
64 case Runtime::kInlineMathSqrt:
65 return ReduceMathSqrt(node);
66 case Runtime::kInlineValueOf:
67 return ReduceValueOf(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 case Runtime::kInlineFixedArrayGet:
69 return ReduceFixedArrayGet(node);
70 case Runtime::kInlineFixedArraySet:
71 return ReduceFixedArraySet(node);
72 case Runtime::kInlineRegExpConstructResult:
73 return ReduceRegExpConstructResult(node);
74 case Runtime::kInlineRegExpExec:
75 return ReduceRegExpExec(node);
76 case Runtime::kInlineRegExpFlags:
77 return ReduceRegExpFlags(node);
78 case Runtime::kInlineRegExpSource:
79 return ReduceRegExpSource(node);
80 case Runtime::kInlineSubString:
81 return ReduceSubString(node);
82 case Runtime::kInlineToInteger:
83 return ReduceToInteger(node);
84 case Runtime::kInlineToLength:
85 return ReduceToLength(node);
86 case Runtime::kInlineToName:
87 return ReduceToName(node);
88 case Runtime::kInlineToNumber:
89 return ReduceToNumber(node);
90 case Runtime::kInlineToObject:
91 return ReduceToObject(node);
92 case Runtime::kInlineToPrimitive:
93 return ReduceToPrimitive(node);
94 case Runtime::kInlineToString:
95 return ReduceToString(node);
96 case Runtime::kInlineCall:
97 return ReduceCall(node);
98 case Runtime::kInlineTailCall:
99 return ReduceTailCall(node);
100 case Runtime::kInlineGetSuperConstructor:
101 return ReduceGetSuperConstructor(node);
102 default:
103 break;
104 }
105 return NoChange();
106}
107
108
109Reduction JSIntrinsicLowering::ReduceCreateIterResultObject(Node* node) {
110 Node* const value = NodeProperties::GetValueInput(node, 0);
111 Node* const done = NodeProperties::GetValueInput(node, 1);
112 Node* const context = NodeProperties::GetContextInput(node);
113 Node* const effect = NodeProperties::GetEffectInput(node);
114 return Change(node, javascript()->CreateIterResultObject(), value, done,
115 context, effect);
116}
117
118
119Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) {
120 Node* high = NodeProperties::GetValueInput(node, 0);
121 Node* low = NodeProperties::GetValueInput(node, 1);
122 Node* value =
123 graph()->NewNode(machine()->Float64InsertHighWord32(),
124 graph()->NewNode(machine()->Float64InsertLowWord32(),
125 jsgraph()->Constant(0), low),
126 high);
127 ReplaceWithValue(node, value);
128 return Replace(value);
129}
130
131
132Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
133 if (mode() != kDeoptimizationEnabled) return NoChange();
134 Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
135 Node* const effect = NodeProperties::GetEffectInput(node);
136 Node* const control = NodeProperties::GetControlInput(node);
137
138 // TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
139 Node* deoptimize =
140 graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
141 frame_state, effect, control);
142 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100143 Revisit(graph()->end());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000144
145 node->TrimInputCount(0);
146 NodeProperties::ChangeOp(node, common()->Dead());
147 return Changed(node);
148}
149
150
151Reduction JSIntrinsicLowering::ReduceDoubleHi(Node* node) {
152 return Change(node, machine()->Float64ExtractHighWord32());
153}
154
155
156Reduction JSIntrinsicLowering::ReduceDoubleLo(Node* node) {
157 return Change(node, machine()->Float64ExtractLowWord32());
158}
159
160
161Reduction JSIntrinsicLowering::ReduceIncrementStatsCounter(Node* node) {
162 if (!FLAG_native_code_counters) return ChangeToUndefined(node);
163 HeapObjectMatcher m(NodeProperties::GetValueInput(node, 0));
164 if (!m.HasValue() || !m.Value()->IsString()) {
165 return ChangeToUndefined(node);
166 }
167 base::SmartArrayPointer<char> name =
168 Handle<String>::cast(m.Value())->ToCString();
169 StatsCounter counter(jsgraph()->isolate(), name.get());
170 if (!counter.Enabled()) return ChangeToUndefined(node);
171
172 Node* effect = NodeProperties::GetEffectInput(node);
173 Node* control = NodeProperties::GetControlInput(node);
174 FieldAccess access = AccessBuilder::ForStatsCounter();
175 Node* cnt = jsgraph()->ExternalConstant(ExternalReference(&counter));
176 Node* load =
177 graph()->NewNode(simplified()->LoadField(access), cnt, effect, control);
178 Node* inc =
179 graph()->NewNode(machine()->Int32Add(), load, jsgraph()->OneConstant());
180 Node* store = graph()->NewNode(simplified()->StoreField(access), cnt, inc,
181 load, control);
182 return ChangeToUndefined(node, store);
183}
184
185
186Reduction JSIntrinsicLowering::ReduceIsInstanceType(
187 Node* node, InstanceType instance_type) {
188 // if (%_IsSmi(value)) {
189 // return false;
190 // } else {
191 // return %_GetInstanceType(%_GetMap(value)) == instance_type;
192 // }
193 Node* value = NodeProperties::GetValueInput(node, 0);
194 Node* effect = NodeProperties::GetEffectInput(node);
195 Node* control = NodeProperties::GetControlInput(node);
196
197 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
198 Node* branch = graph()->NewNode(common()->Branch(), check, control);
199
200 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
201 Node* etrue = effect;
202 Node* vtrue = jsgraph()->FalseConstant();
203
204 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
205 Node* efalse = graph()->NewNode(
206 simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
207 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), value,
208 effect, if_false),
209 effect, if_false);
210 Node* vfalse = graph()->NewNode(machine()->Word32Equal(), efalse,
211 jsgraph()->Int32Constant(instance_type));
212
213 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
214
215 // Replace all effect uses of {node} with the {ephi}.
216 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
217 ReplaceWithValue(node, node, ephi);
218
219 // Turn the {node} into a Phi.
220 return Change(node, common()->Phi(MachineRepresentation::kTagged, 2), vtrue,
221 vfalse, merge);
222}
223
224
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000225Reduction JSIntrinsicLowering::ReduceIsJSReceiver(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100226 return Change(node, simplified()->ObjectIsReceiver());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000227}
228
229
230Reduction JSIntrinsicLowering::ReduceIsSmi(Node* node) {
231 return Change(node, simplified()->ObjectIsSmi());
232}
233
234
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000235Reduction JSIntrinsicLowering::ReduceMathClz32(Node* node) {
236 return Change(node, machine()->Word32Clz());
237}
238
239
240Reduction JSIntrinsicLowering::ReduceMathFloor(Node* node) {
241 if (!machine()->Float64RoundDown().IsSupported()) return NoChange();
242 return Change(node, machine()->Float64RoundDown().op());
243}
244
245
246Reduction JSIntrinsicLowering::ReduceMathSqrt(Node* node) {
247 return Change(node, machine()->Float64Sqrt());
248}
249
250
251Reduction JSIntrinsicLowering::ReduceValueOf(Node* node) {
252 // if (%_IsSmi(value)) {
253 // return value;
254 // } else if (%_GetInstanceType(%_GetMap(value)) == JS_VALUE_TYPE) {
255 // return %_GetValue(value);
256 // } else {
257 // return value;
258 // }
259 const Operator* const merge_op = common()->Merge(2);
260 const Operator* const ephi_op = common()->EffectPhi(2);
261 const Operator* const phi_op =
262 common()->Phi(MachineRepresentation::kTagged, 2);
263
264 Node* value = NodeProperties::GetValueInput(node, 0);
265 Node* effect = NodeProperties::GetEffectInput(node);
266 Node* control = NodeProperties::GetControlInput(node);
267
268 Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
269 Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
270
271 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
272 Node* etrue0 = effect;
273 Node* vtrue0 = value;
274
275 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
276 Node* efalse0;
277 Node* vfalse0;
278 {
279 Node* check1 = graph()->NewNode(
280 machine()->Word32Equal(),
281 graph()->NewNode(
282 simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
283 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
284 value, effect, if_false0),
285 effect, if_false0),
286 jsgraph()->Int32Constant(JS_VALUE_TYPE));
287 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
288
289 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
290 Node* etrue1 =
291 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForValue()),
292 value, effect, if_true1);
293 Node* vtrue1 = etrue1;
294
295 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
296 Node* efalse1 = effect;
297 Node* vfalse1 = value;
298
299 Node* merge1 = graph()->NewNode(merge_op, if_true1, if_false1);
300 efalse0 = graph()->NewNode(ephi_op, etrue1, efalse1, merge1);
301 vfalse0 = graph()->NewNode(phi_op, vtrue1, vfalse1, merge1);
302 }
303
304 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
305
306 // Replace all effect uses of {node} with the {ephi0}.
307 Node* ephi0 = graph()->NewNode(ephi_op, etrue0, efalse0, merge0);
308 ReplaceWithValue(node, node, ephi0);
309
310 // Turn the {node} into a Phi.
311 return Change(node, phi_op, vtrue0, vfalse0, merge0);
312}
313
314
315Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) {
316 // Replace all effect uses of {node} with the effect dependency.
317 RelaxEffectsAndControls(node);
318 // Remove the inputs corresponding to context, effect and control.
319 NodeProperties::RemoveNonValueInputs(node);
320 // Finally update the operator to the new one.
321 NodeProperties::ChangeOp(node, op);
322 return Changed(node);
323}
324
325
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000326Reduction JSIntrinsicLowering::ReduceFixedArrayGet(Node* node) {
327 Node* base = node->InputAt(0);
328 Node* index = node->InputAt(1);
329 Node* effect = NodeProperties::GetEffectInput(node);
330 Node* control = NodeProperties::GetControlInput(node);
331 return Change(
332 node, simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()),
333 base, index, effect, control);
334}
335
336
337Reduction JSIntrinsicLowering::ReduceFixedArraySet(Node* node) {
338 Node* base = node->InputAt(0);
339 Node* index = node->InputAt(1);
340 Node* value = node->InputAt(2);
341 Node* effect = NodeProperties::GetEffectInput(node);
342 Node* control = NodeProperties::GetControlInput(node);
343 Node* store = (graph()->NewNode(
344 simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()), base,
345 index, value, effect, control));
346 ReplaceWithValue(node, value, store);
347 return Changed(store);
348}
349
350
351Reduction JSIntrinsicLowering::ReduceRegExpConstructResult(Node* node) {
352 // TODO(bmeurer): Introduce JSCreateRegExpResult?
353 return Change(node, CodeFactory::RegExpConstructResult(isolate()), 0);
354}
355
356
357Reduction JSIntrinsicLowering::ReduceRegExpExec(Node* node) {
358 return Change(node, CodeFactory::RegExpExec(isolate()), 4);
359}
360
361
362Reduction JSIntrinsicLowering::ReduceRegExpFlags(Node* node) {
363 Node* const receiver = NodeProperties::GetValueInput(node, 0);
364 Node* const effect = NodeProperties::GetEffectInput(node);
365 Node* const control = NodeProperties::GetControlInput(node);
366 Operator const* const op =
367 simplified()->LoadField(AccessBuilder::ForJSRegExpFlags());
368 return Change(node, op, receiver, effect, control);
369}
370
371
372Reduction JSIntrinsicLowering::ReduceRegExpSource(Node* node) {
373 Node* const receiver = NodeProperties::GetValueInput(node, 0);
374 Node* const effect = NodeProperties::GetEffectInput(node);
375 Node* const control = NodeProperties::GetControlInput(node);
376 Operator const* const op =
377 simplified()->LoadField(AccessBuilder::ForJSRegExpSource());
378 return Change(node, op, receiver, effect, control);
379}
380
381
382Reduction JSIntrinsicLowering::ReduceSubString(Node* node) {
383 return Change(node, CodeFactory::SubString(isolate()), 3);
384}
385
386
387Reduction JSIntrinsicLowering::ReduceToInteger(Node* node) {
388 Node* value = NodeProperties::GetValueInput(node, 0);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100389 Node* context = NodeProperties::GetContextInput(node);
390 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
391 Node* effect = NodeProperties::GetEffectInput(node);
392 Node* control = NodeProperties::GetControlInput(node);
393
394 // ToInteger is a no-op on integer values and -0.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000395 Type* value_type = NodeProperties::GetType(value);
396 if (value_type->Is(type_cache().kIntegerOrMinusZero)) {
397 ReplaceWithValue(node, value);
398 return Replace(value);
399 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100400
401 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
402 Node* branch =
403 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
404
405 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
406 Node* etrue = effect;
407 Node* vtrue = value;
408
409 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
410 Node* efalse = effect;
411 Node* vfalse;
412 {
413 vfalse = efalse =
414 graph()->NewNode(javascript()->CallRuntime(Runtime::kToInteger), value,
415 context, frame_state, efalse, if_false);
416 if_false = graph()->NewNode(common()->IfSuccess(), vfalse);
417 }
418
419 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
420 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
421 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
422 vtrue, vfalse, control);
423 // TODO(bmeurer, mstarzinger): Rewire IfException inputs to {vfalse}.
424 ReplaceWithValue(node, value, effect, control);
425 return Changed(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000426}
427
428
429Reduction JSIntrinsicLowering::ReduceToName(Node* node) {
430 NodeProperties::ChangeOp(node, javascript()->ToName());
431 return Changed(node);
432}
433
434
435Reduction JSIntrinsicLowering::ReduceToNumber(Node* node) {
436 NodeProperties::ChangeOp(node, javascript()->ToNumber());
437 return Changed(node);
438}
439
440
441Reduction JSIntrinsicLowering::ReduceToLength(Node* node) {
442 Node* value = NodeProperties::GetValueInput(node, 0);
443 Type* value_type = NodeProperties::GetType(value);
444 if (value_type->Is(type_cache().kIntegerOrMinusZero)) {
445 if (value_type->Max() <= 0.0) {
446 value = jsgraph()->ZeroConstant();
447 } else if (value_type->Min() >= kMaxSafeInteger) {
448 value = jsgraph()->Constant(kMaxSafeInteger);
449 } else {
450 if (value_type->Min() <= 0.0) {
451 value = graph()->NewNode(
452 common()->Select(MachineRepresentation::kTagged),
453 graph()->NewNode(simplified()->NumberLessThanOrEqual(), value,
454 jsgraph()->ZeroConstant()),
455 jsgraph()->ZeroConstant(), value);
456 value_type = Type::Range(0.0, value_type->Max(), graph()->zone());
457 NodeProperties::SetType(value, value_type);
458 }
459 if (value_type->Max() > kMaxSafeInteger) {
460 value = graph()->NewNode(
461 common()->Select(MachineRepresentation::kTagged),
462 graph()->NewNode(simplified()->NumberLessThanOrEqual(),
463 jsgraph()->Constant(kMaxSafeInteger), value),
464 jsgraph()->Constant(kMaxSafeInteger), value);
465 value_type =
466 Type::Range(value_type->Min(), kMaxSafeInteger, graph()->zone());
467 NodeProperties::SetType(value, value_type);
468 }
469 }
470 ReplaceWithValue(node, value);
471 return Replace(value);
472 }
473 return Change(node, CodeFactory::ToLength(isolate()), 0);
474}
475
476
477Reduction JSIntrinsicLowering::ReduceToObject(Node* node) {
478 NodeProperties::ChangeOp(node, javascript()->ToObject());
479 return Changed(node);
480}
481
482
483Reduction JSIntrinsicLowering::ReduceToPrimitive(Node* node) {
484 Node* value = NodeProperties::GetValueInput(node, 0);
485 Type* value_type = NodeProperties::GetType(value);
486 if (value_type->Is(Type::Primitive())) {
487 ReplaceWithValue(node, value);
488 return Replace(value);
489 }
490 return NoChange();
491}
492
493
494Reduction JSIntrinsicLowering::ReduceToString(Node* node) {
495 NodeProperties::ChangeOp(node, javascript()->ToString());
496 return Changed(node);
497}
498
499
500Reduction JSIntrinsicLowering::ReduceCall(Node* node) {
501 size_t const arity = CallRuntimeParametersOf(node->op()).arity();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100502 NodeProperties::ChangeOp(node,
503 javascript()->CallFunction(arity, VectorSlotPair(),
504 ConvertReceiverMode::kAny,
505 TailCallMode::kDisallow));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000506 return Changed(node);
507}
508
509
510Reduction JSIntrinsicLowering::ReduceTailCall(Node* node) {
511 size_t const arity = CallRuntimeParametersOf(node->op()).arity();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100512 NodeProperties::ChangeOp(node,
513 javascript()->CallFunction(arity, VectorSlotPair(),
514 ConvertReceiverMode::kAny,
515 TailCallMode::kAllow));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000516 return Changed(node);
517}
518
519
520Reduction JSIntrinsicLowering::ReduceGetSuperConstructor(Node* node) {
521 Node* active_function = NodeProperties::GetValueInput(node, 0);
522 Node* effect = NodeProperties::GetEffectInput(node);
523 Node* control = NodeProperties::GetControlInput(node);
524 Node* active_function_map = effect =
525 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
526 active_function, effect, control);
527 return Change(node, simplified()->LoadField(AccessBuilder::ForMapPrototype()),
528 active_function_map, effect, control);
529}
530
531
532Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
533 Node* b) {
534 RelaxControls(node);
535 node->ReplaceInput(0, a);
536 node->ReplaceInput(1, b);
537 node->TrimInputCount(2);
538 NodeProperties::ChangeOp(node, op);
539 return Changed(node);
540}
541
542
543Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
544 Node* b, Node* c) {
545 RelaxControls(node);
546 node->ReplaceInput(0, a);
547 node->ReplaceInput(1, b);
548 node->ReplaceInput(2, c);
549 node->TrimInputCount(3);
550 NodeProperties::ChangeOp(node, op);
551 return Changed(node);
552}
553
554
555Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
556 Node* b, Node* c, Node* d) {
557 RelaxControls(node);
558 node->ReplaceInput(0, a);
559 node->ReplaceInput(1, b);
560 node->ReplaceInput(2, c);
561 node->ReplaceInput(3, d);
562 node->TrimInputCount(4);
563 NodeProperties::ChangeOp(node, op);
564 return Changed(node);
565}
566
567
568Reduction JSIntrinsicLowering::ChangeToUndefined(Node* node, Node* effect) {
569 ReplaceWithValue(node, jsgraph()->UndefinedConstant(), effect);
570 return Changed(node);
571}
572
573
574Reduction JSIntrinsicLowering::Change(Node* node, Callable const& callable,
575 int stack_parameter_count) {
576 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
577 isolate(), graph()->zone(), callable.descriptor(), stack_parameter_count,
578 CallDescriptor::kNeedsFrameState, node->op()->properties());
579 node->InsertInput(graph()->zone(), 0,
580 jsgraph()->HeapConstant(callable.code()));
581 NodeProperties::ChangeOp(node, common()->Call(desc));
582 return Changed(node);
583}
584
585
586Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); }
587
588
589Isolate* JSIntrinsicLowering::isolate() const { return jsgraph()->isolate(); }
590
591
592CommonOperatorBuilder* JSIntrinsicLowering::common() const {
593 return jsgraph()->common();
594}
595
596JSOperatorBuilder* JSIntrinsicLowering::javascript() const {
597 return jsgraph_->javascript();
598}
599
600
601MachineOperatorBuilder* JSIntrinsicLowering::machine() const {
602 return jsgraph()->machine();
603}
604
605
606SimplifiedOperatorBuilder* JSIntrinsicLowering::simplified() const {
607 return jsgraph()->simplified();
608}
609
610} // namespace compiler
611} // namespace internal
612} // namespace v8