blob: b7f6b129e548340287492e13cb0d3c47a9a74f66 [file] [log] [blame]
Ben Murdochc5610432016-08-08 18:44:38 +01001// 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/effect-control-linearizer.h"
6
7#include "src/code-factory.h"
8#include "src/compiler/access-builder.h"
9#include "src/compiler/js-graph.h"
10#include "src/compiler/linkage.h"
11#include "src/compiler/node-properties.h"
12#include "src/compiler/node.h"
13#include "src/compiler/schedule.h"
14
15namespace v8 {
16namespace internal {
17namespace compiler {
18
19EffectControlLinearizer::EffectControlLinearizer(JSGraph* js_graph,
20 Schedule* schedule,
21 Zone* temp_zone)
22 : js_graph_(js_graph), schedule_(schedule), temp_zone_(temp_zone) {}
23
24Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); }
25CommonOperatorBuilder* EffectControlLinearizer::common() const {
26 return js_graph_->common();
27}
28SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const {
29 return js_graph_->simplified();
30}
31MachineOperatorBuilder* EffectControlLinearizer::machine() const {
32 return js_graph_->machine();
33}
34
35namespace {
36
37struct BlockEffectControlData {
38 Node* current_effect = nullptr; // New effect.
39 Node* current_control = nullptr; // New control.
Ben Murdoch61f157c2016-09-16 13:49:30 +010040 Node* current_frame_state = nullptr; // New frame state.
Ben Murdochc5610432016-08-08 18:44:38 +010041};
42
43// Effect phis that need to be updated after the first pass.
44struct PendingEffectPhi {
45 Node* effect_phi;
46 BasicBlock* block;
47
48 PendingEffectPhi(Node* effect_phi, BasicBlock* block)
49 : effect_phi(effect_phi), block(block) {}
50};
51
52void UpdateEffectPhi(Node* node, BasicBlock* block,
53 ZoneVector<BlockEffectControlData>* block_effects) {
54 // Update all inputs to an effect phi with the effects from the given
55 // block->effect map.
56 DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
57 DCHECK_EQ(node->op()->EffectInputCount(), block->PredecessorCount());
58 for (int i = 0; i < node->op()->EffectInputCount(); i++) {
59 Node* input = node->InputAt(i);
60 BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
61 Node* input_effect =
62 (*block_effects)[predecessor->rpo_number()].current_effect;
63 if (input != input_effect) {
64 node->ReplaceInput(i, input_effect);
65 }
66 }
67}
68
69void UpdateBlockControl(BasicBlock* block,
70 ZoneVector<BlockEffectControlData>* block_effects) {
71 Node* control = block->NodeAt(0);
72 DCHECK(NodeProperties::IsControl(control));
73
74 // Do not rewire the end node.
75 if (control->opcode() == IrOpcode::kEnd) return;
76
77 // Update all inputs to the given control node with the correct control.
78 DCHECK_EQ(control->op()->ControlInputCount(), block->PredecessorCount());
79 for (int i = 0; i < control->op()->ControlInputCount(); i++) {
80 Node* input = NodeProperties::GetControlInput(control, i);
81 BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
82 Node* input_control =
83 (*block_effects)[predecessor->rpo_number()].current_control;
84 if (input != input_control) {
85 NodeProperties::ReplaceControlInput(control, input_control, i);
86 }
87 }
88}
89
90bool HasIncomingBackEdges(BasicBlock* block) {
91 for (BasicBlock* pred : block->predecessors()) {
92 if (pred->rpo_number() >= block->rpo_number()) {
93 return true;
94 }
95 }
96 return false;
97}
98
99void RemoveRegionNode(Node* node) {
100 DCHECK(IrOpcode::kFinishRegion == node->opcode() ||
101 IrOpcode::kBeginRegion == node->opcode());
102 // Update the value/context uses to the value input of the finish node and
103 // the effect uses to the effect input.
104 for (Edge edge : node->use_edges()) {
105 DCHECK(!edge.from()->IsDead());
106 if (NodeProperties::IsEffectEdge(edge)) {
107 edge.UpdateTo(NodeProperties::GetEffectInput(node));
108 } else {
109 DCHECK(!NodeProperties::IsControlEdge(edge));
110 DCHECK(!NodeProperties::IsFrameStateEdge(edge));
111 edge.UpdateTo(node->InputAt(0));
112 }
113 }
114 node->Kill();
115}
116
117} // namespace
118
119void EffectControlLinearizer::Run() {
120 ZoneVector<BlockEffectControlData> block_effects(temp_zone());
121 ZoneVector<PendingEffectPhi> pending_effect_phis(temp_zone());
122 ZoneVector<BasicBlock*> pending_block_controls(temp_zone());
123 block_effects.resize(schedule()->RpoBlockCount());
124 NodeVector inputs_buffer(temp_zone());
125
126 for (BasicBlock* block : *(schedule()->rpo_order())) {
127 size_t instr = 0;
128
129 // The control node should be the first.
130 Node* control = block->NodeAt(instr);
131 DCHECK(NodeProperties::IsControl(control));
132 // Update the control inputs.
133 if (HasIncomingBackEdges(block)) {
134 // If there are back edges, we need to update later because we have not
135 // computed the control yet. This should only happen for loops.
136 DCHECK_EQ(IrOpcode::kLoop, control->opcode());
137 pending_block_controls.push_back(block);
138 } else {
139 // If there are no back edges, we can update now.
140 UpdateBlockControl(block, &block_effects);
141 }
142 instr++;
143
144 // Iterate over the phis and update the effect phis.
145 Node* effect = nullptr;
146 Node* terminate = nullptr;
147 for (; instr < block->NodeCount(); instr++) {
148 Node* node = block->NodeAt(instr);
149 // Only go through the phis and effect phis.
150 if (node->opcode() == IrOpcode::kEffectPhi) {
151 // There should be at most one effect phi in a block.
152 DCHECK_NULL(effect);
153 // IfException blocks should not have effect phis.
154 DCHECK_NE(IrOpcode::kIfException, control->opcode());
155 effect = node;
156
157 // Make sure we update the inputs to the incoming blocks' effects.
158 if (HasIncomingBackEdges(block)) {
159 // In case of loops, we do not update the effect phi immediately
160 // because the back predecessor has not been handled yet. We just
161 // record the effect phi for later processing.
162 pending_effect_phis.push_back(PendingEffectPhi(node, block));
163 } else {
164 UpdateEffectPhi(node, block, &block_effects);
165 }
166 } else if (node->opcode() == IrOpcode::kPhi) {
167 // Just skip phis.
168 } else if (node->opcode() == IrOpcode::kTerminate) {
169 DCHECK(terminate == nullptr);
170 terminate = node;
171 } else {
172 break;
173 }
174 }
175
176 if (effect == nullptr) {
177 // There was no effect phi.
178 DCHECK(!HasIncomingBackEdges(block));
179 if (block == schedule()->start()) {
180 // Start block => effect is start.
181 DCHECK_EQ(graph()->start(), control);
182 effect = graph()->start();
183 } else if (control->opcode() == IrOpcode::kEnd) {
184 // End block is just a dummy, no effect needed.
185 DCHECK_EQ(BasicBlock::kNone, block->control());
186 DCHECK_EQ(1u, block->size());
187 effect = nullptr;
188 } else {
189 // If all the predecessors have the same effect, we can use it
190 // as our current effect.
191 int rpo_number = block->PredecessorAt(0)->rpo_number();
192 effect = block_effects[rpo_number].current_effect;
193 for (size_t i = 1; i < block->PredecessorCount(); i++) {
194 int rpo_number = block->PredecessorAt(i)->rpo_number();
195 if (block_effects[rpo_number].current_effect != effect) {
196 effect = nullptr;
197 break;
198 }
199 }
200 if (effect == nullptr) {
201 DCHECK_NE(IrOpcode::kIfException, control->opcode());
202 // The input blocks do not have the same effect. We have
203 // to create an effect phi node.
204 inputs_buffer.clear();
205 inputs_buffer.resize(block->PredecessorCount(), graph()->start());
206 inputs_buffer.push_back(control);
207 effect = graph()->NewNode(
208 common()->EffectPhi(static_cast<int>(block->PredecessorCount())),
209 static_cast<int>(inputs_buffer.size()), &(inputs_buffer.front()));
210 // Let us update the effect phi node later.
211 pending_effect_phis.push_back(PendingEffectPhi(effect, block));
212 } else if (control->opcode() == IrOpcode::kIfException) {
213 // The IfException is connected into the effect chain, so we need
214 // to update the effect here.
215 NodeProperties::ReplaceEffectInput(control, effect);
216 effect = control;
217 }
218 }
219 }
220
221 // Fixup the Terminate node.
222 if (terminate != nullptr) {
223 NodeProperties::ReplaceEffectInput(terminate, effect);
224 }
225
Ben Murdoch61f157c2016-09-16 13:49:30 +0100226 // The frame state at block entry is determined by the frame states leaving
227 // all predecessors. In case there is no frame state dominating this block,
228 // we can rely on a checkpoint being present before the next deoptimization.
229 // TODO(mstarzinger): Eventually we will need to go hunt for a frame state
230 // once deoptimizing nodes roam freely through the schedule.
231 Node* frame_state = nullptr;
232 if (block != schedule()->start()) {
233 // If all the predecessors have the same effect, we can use it
234 // as our current effect.
235 int rpo_number = block->PredecessorAt(0)->rpo_number();
236 frame_state = block_effects[rpo_number].current_frame_state;
237 for (size_t i = 1; i < block->PredecessorCount(); i++) {
238 int rpo_number = block->PredecessorAt(i)->rpo_number();
239 if (block_effects[rpo_number].current_frame_state != frame_state) {
240 frame_state = nullptr;
241 break;
242 }
243 }
244 }
245
Ben Murdochc5610432016-08-08 18:44:38 +0100246 // Process the ordinary instructions.
247 for (; instr < block->NodeCount(); instr++) {
248 Node* node = block->NodeAt(instr);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100249 ProcessNode(node, &frame_state, &effect, &control);
Ben Murdochc5610432016-08-08 18:44:38 +0100250 }
251
252 switch (block->control()) {
253 case BasicBlock::kGoto:
254 case BasicBlock::kNone:
255 break;
256
257 case BasicBlock::kCall:
258 case BasicBlock::kTailCall:
259 case BasicBlock::kBranch:
260 case BasicBlock::kSwitch:
261 case BasicBlock::kReturn:
262 case BasicBlock::kDeoptimize:
263 case BasicBlock::kThrow:
Ben Murdoch61f157c2016-09-16 13:49:30 +0100264 ProcessNode(block->control_input(), &frame_state, &effect, &control);
Ben Murdochc5610432016-08-08 18:44:38 +0100265 break;
266 }
267
268 // Store the effect for later use.
269 block_effects[block->rpo_number()].current_effect = effect;
270 block_effects[block->rpo_number()].current_control = control;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100271 block_effects[block->rpo_number()].current_frame_state = frame_state;
Ben Murdochc5610432016-08-08 18:44:38 +0100272 }
273
274 // Update the incoming edges of the effect phis that could not be processed
275 // during the first pass (because they could have incoming back edges).
276 for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) {
277 UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
278 &block_effects);
279 }
280 for (BasicBlock* pending_block_control : pending_block_controls) {
281 UpdateBlockControl(pending_block_control, &block_effects);
282 }
283}
284
285namespace {
286
287void TryScheduleCallIfSuccess(Node* node, Node** control) {
288 // Schedule the call's IfSuccess node if there is no exception use.
289 if (!NodeProperties::IsExceptionalCall(node)) {
290 for (Edge edge : node->use_edges()) {
291 if (NodeProperties::IsControlEdge(edge) &&
292 edge.from()->opcode() == IrOpcode::kIfSuccess) {
293 *control = edge.from();
294 }
295 }
296 }
297}
298
299} // namespace
300
Ben Murdoch61f157c2016-09-16 13:49:30 +0100301void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state,
302 Node** effect, Node** control) {
Ben Murdochc5610432016-08-08 18:44:38 +0100303 // If the node needs to be wired into the effect/control chain, do this
Ben Murdoch61f157c2016-09-16 13:49:30 +0100304 // here. Pass current frame state for lowering to eager deoptimization.
305 if (TryWireInStateEffect(node, *frame_state, effect, control)) {
Ben Murdochc5610432016-08-08 18:44:38 +0100306 return;
307 }
308
Ben Murdoch61f157c2016-09-16 13:49:30 +0100309 // If the node has a visible effect, then there must be a checkpoint in the
310 // effect chain before we are allowed to place another eager deoptimization
311 // point. We zap the frame state to ensure this invariant is maintained.
312 if (region_observability_ == RegionObservability::kObservable &&
313 !node->op()->HasProperty(Operator::kNoWrite)) {
314 *frame_state = nullptr;
315 }
316
Ben Murdochc5610432016-08-08 18:44:38 +0100317 // Remove the end markers of 'atomic' allocation region because the
318 // region should be wired-in now.
Ben Murdoch61f157c2016-09-16 13:49:30 +0100319 if (node->opcode() == IrOpcode::kFinishRegion) {
320 // Reset the current region observability.
321 region_observability_ = RegionObservability::kObservable;
322 // Update the value uses to the value input of the finish node and
323 // the effect uses to the effect input.
324 return RemoveRegionNode(node);
325 }
326 if (node->opcode() == IrOpcode::kBeginRegion) {
327 // Determine the observability for this region and use that for all
328 // nodes inside the region (i.e. ignore the absence of kNoWrite on
329 // StoreField and other operators).
330 DCHECK_NE(RegionObservability::kNotObservable, region_observability_);
331 region_observability_ = RegionObservabilityOf(node->op());
Ben Murdochc5610432016-08-08 18:44:38 +0100332 // Update the value uses to the value input of the finish node and
333 // the effect uses to the effect input.
334 return RemoveRegionNode(node);
335 }
336
Ben Murdoch61f157c2016-09-16 13:49:30 +0100337 // Special treatment for checkpoint nodes.
338 if (node->opcode() == IrOpcode::kCheckpoint) {
Ben Murdochc5610432016-08-08 18:44:38 +0100339 // Unlink the check point; effect uses will be updated to the incoming
Ben Murdoch61f157c2016-09-16 13:49:30 +0100340 // effect that is passed. The frame state is preserved for lowering.
341 DCHECK_EQ(RegionObservability::kObservable, region_observability_);
342 *frame_state = NodeProperties::GetFrameStateInput(node, 0);
343 node->TrimInputCount(0);
Ben Murdochc5610432016-08-08 18:44:38 +0100344 return;
345 }
346
347 if (node->opcode() == IrOpcode::kIfSuccess) {
348 // We always schedule IfSuccess with its call, so skip it here.
349 DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode());
350 // The IfSuccess node should not belong to an exceptional call node
351 // because such IfSuccess nodes should only start a basic block (and
352 // basic block start nodes are not handled in the ProcessNode method).
353 DCHECK(!NodeProperties::IsExceptionalCall(node->InputAt(0)));
354 return;
355 }
356
357 // If the node takes an effect, replace with the current one.
358 if (node->op()->EffectInputCount() > 0) {
359 DCHECK_EQ(1, node->op()->EffectInputCount());
360 Node* input_effect = NodeProperties::GetEffectInput(node);
361
362 if (input_effect != *effect) {
363 NodeProperties::ReplaceEffectInput(node, *effect);
364 }
365
366 // If the node produces an effect, update our current effect. (However,
367 // ignore new effect chains started with ValueEffect.)
368 if (node->op()->EffectOutputCount() > 0) {
369 DCHECK_EQ(1, node->op()->EffectOutputCount());
370 *effect = node;
371 }
372 } else {
373 // New effect chain is only started with a Start or ValueEffect node.
374 DCHECK(node->op()->EffectOutputCount() == 0 ||
375 node->opcode() == IrOpcode::kStart);
376 }
377
378 // Rewire control inputs.
379 for (int i = 0; i < node->op()->ControlInputCount(); i++) {
380 NodeProperties::ReplaceControlInput(node, *control, i);
381 }
382 // Update the current control and wire IfSuccess right after calls.
383 if (node->op()->ControlOutputCount() > 0) {
384 *control = node;
385 if (node->opcode() == IrOpcode::kCall) {
386 // Schedule the call's IfSuccess node (if there is no exception use).
387 TryScheduleCallIfSuccess(node, control);
388 }
389 }
390}
391
Ben Murdoch61f157c2016-09-16 13:49:30 +0100392bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
393 Node* frame_state,
394 Node** effect,
Ben Murdochc5610432016-08-08 18:44:38 +0100395 Node** control) {
396 ValueEffectControl state(nullptr, nullptr, nullptr);
397 switch (node->opcode()) {
398 case IrOpcode::kTypeGuard:
399 state = LowerTypeGuard(node, *effect, *control);
400 break;
401 case IrOpcode::kChangeBitToTagged:
402 state = LowerChangeBitToTagged(node, *effect, *control);
403 break;
404 case IrOpcode::kChangeInt31ToTaggedSigned:
405 state = LowerChangeInt31ToTaggedSigned(node, *effect, *control);
406 break;
407 case IrOpcode::kChangeInt32ToTagged:
408 state = LowerChangeInt32ToTagged(node, *effect, *control);
409 break;
410 case IrOpcode::kChangeUint32ToTagged:
411 state = LowerChangeUint32ToTagged(node, *effect, *control);
412 break;
413 case IrOpcode::kChangeFloat64ToTagged:
414 state = LowerChangeFloat64ToTagged(node, *effect, *control);
415 break;
416 case IrOpcode::kChangeTaggedSignedToInt32:
417 state = LowerChangeTaggedSignedToInt32(node, *effect, *control);
418 break;
419 case IrOpcode::kChangeTaggedToBit:
420 state = LowerChangeTaggedToBit(node, *effect, *control);
421 break;
422 case IrOpcode::kChangeTaggedToInt32:
423 state = LowerChangeTaggedToInt32(node, *effect, *control);
424 break;
425 case IrOpcode::kChangeTaggedToUint32:
426 state = LowerChangeTaggedToUint32(node, *effect, *control);
427 break;
428 case IrOpcode::kChangeTaggedToFloat64:
429 state = LowerChangeTaggedToFloat64(node, *effect, *control);
430 break;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100431 case IrOpcode::kTruncateTaggedToFloat64:
432 state = LowerTruncateTaggedToFloat64(node, *effect, *control);
433 break;
434 case IrOpcode::kCheckBounds:
435 state = LowerCheckBounds(node, frame_state, *effect, *control);
436 break;
437 case IrOpcode::kCheckTaggedPointer:
438 state = LowerCheckTaggedPointer(node, frame_state, *effect, *control);
439 break;
440 case IrOpcode::kCheckTaggedSigned:
441 state = LowerCheckTaggedSigned(node, frame_state, *effect, *control);
442 break;
443 case IrOpcode::kCheckedInt32Add:
444 state = LowerCheckedInt32Add(node, frame_state, *effect, *control);
445 break;
446 case IrOpcode::kCheckedInt32Sub:
447 state = LowerCheckedInt32Sub(node, frame_state, *effect, *control);
448 break;
449 case IrOpcode::kCheckedUint32ToInt32:
450 state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control);
451 break;
452 case IrOpcode::kCheckedFloat64ToInt32:
453 state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control);
454 break;
455 case IrOpcode::kCheckedTaggedToInt32:
456 state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control);
457 break;
458 case IrOpcode::kCheckedTaggedToFloat64:
459 state = LowerCheckedTaggedToFloat64(node, frame_state, *effect, *control);
460 break;
Ben Murdochc5610432016-08-08 18:44:38 +0100461 case IrOpcode::kTruncateTaggedToWord32:
462 state = LowerTruncateTaggedToWord32(node, *effect, *control);
463 break;
464 case IrOpcode::kObjectIsCallable:
465 state = LowerObjectIsCallable(node, *effect, *control);
466 break;
467 case IrOpcode::kObjectIsNumber:
468 state = LowerObjectIsNumber(node, *effect, *control);
469 break;
470 case IrOpcode::kObjectIsReceiver:
471 state = LowerObjectIsReceiver(node, *effect, *control);
472 break;
473 case IrOpcode::kObjectIsSmi:
474 state = LowerObjectIsSmi(node, *effect, *control);
475 break;
476 case IrOpcode::kObjectIsString:
477 state = LowerObjectIsString(node, *effect, *control);
478 break;
479 case IrOpcode::kObjectIsUndetectable:
480 state = LowerObjectIsUndetectable(node, *effect, *control);
481 break;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100482 case IrOpcode::kStringFromCharCode:
483 state = LowerStringFromCharCode(node, *effect, *control);
484 break;
485 case IrOpcode::kCheckFloat64Hole:
486 state = LowerCheckFloat64Hole(node, frame_state, *effect, *control);
487 break;
488 case IrOpcode::kCheckTaggedHole:
489 state = LowerCheckTaggedHole(node, frame_state, *effect, *control);
490 break;
491 case IrOpcode::kPlainPrimitiveToNumber:
492 state = LowerPlainPrimitiveToNumber(node, *effect, *control);
493 break;
494 case IrOpcode::kPlainPrimitiveToWord32:
495 state = LowerPlainPrimitiveToWord32(node, *effect, *control);
496 break;
497 case IrOpcode::kPlainPrimitiveToFloat64:
498 state = LowerPlainPrimitiveToFloat64(node, *effect, *control);
499 break;
Ben Murdochc5610432016-08-08 18:44:38 +0100500 default:
501 return false;
502 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100503 NodeProperties::ReplaceUses(node, state.value, state.effect, state.control);
Ben Murdochc5610432016-08-08 18:44:38 +0100504 *effect = state.effect;
505 *control = state.control;
506 return true;
507}
508
509EffectControlLinearizer::ValueEffectControl
510EffectControlLinearizer::LowerTypeGuard(Node* node, Node* effect,
511 Node* control) {
512 Node* value = node->InputAt(0);
513 return ValueEffectControl(value, effect, control);
514}
515
516EffectControlLinearizer::ValueEffectControl
517EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect,
518 Node* control) {
519 Node* value = node->InputAt(0);
520
521 Node* value32 = graph()->NewNode(machine()->RoundFloat64ToInt32(), value);
522 Node* check_same = graph()->NewNode(
523 machine()->Float64Equal(), value,
524 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32));
525 Node* branch_same = graph()->NewNode(common()->Branch(), check_same, control);
526
527 Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_same);
528 Node* vsmi;
529 Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same);
530
531 // Check if {value} is -0.
532 Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32,
533 jsgraph()->Int32Constant(0));
534 Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse),
535 check_zero, if_smi);
536
537 Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero);
538 Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero);
539
540 // In case of 0, we need to check the high bits for the IEEE -0 pattern.
541 Node* check_negative = graph()->NewNode(
542 machine()->Int32LessThan(),
543 graph()->NewNode(machine()->Float64ExtractHighWord32(), value),
544 jsgraph()->Int32Constant(0));
545 Node* branch_negative = graph()->NewNode(common()->Branch(BranchHint::kFalse),
546 check_negative, if_zero);
547
548 Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative);
549 Node* if_notnegative = graph()->NewNode(common()->IfFalse(), branch_negative);
550
551 // We need to create a box for negative 0.
552 if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative);
553 if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative);
554
555 // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit
556 // machines we need to deal with potential overflow and fallback to boxing.
557 if (machine()->Is64()) {
558 vsmi = ChangeInt32ToSmi(value32);
559 } else {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100560 Node* smi_tag = graph()->NewNode(machine()->Int32AddWithOverflow(), value32,
561 value32, if_smi);
Ben Murdochc5610432016-08-08 18:44:38 +0100562
Ben Murdoch61f157c2016-09-16 13:49:30 +0100563 Node* check_ovf =
564 graph()->NewNode(common()->Projection(1), smi_tag, if_smi);
Ben Murdochc5610432016-08-08 18:44:38 +0100565 Node* branch_ovf = graph()->NewNode(common()->Branch(BranchHint::kFalse),
566 check_ovf, if_smi);
567
568 Node* if_ovf = graph()->NewNode(common()->IfTrue(), branch_ovf);
569 if_box = graph()->NewNode(common()->Merge(2), if_ovf, if_box);
570
571 if_smi = graph()->NewNode(common()->IfFalse(), branch_ovf);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100572 vsmi = graph()->NewNode(common()->Projection(0), smi_tag, if_smi);
Ben Murdochc5610432016-08-08 18:44:38 +0100573 }
574
575 // Allocate the box for the {value}.
576 ValueEffectControl box = AllocateHeapNumberWithValue(value, effect, if_box);
577
578 control = graph()->NewNode(common()->Merge(2), if_smi, box.control);
579 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
580 vsmi, box.value, control);
581 effect =
582 graph()->NewNode(common()->EffectPhi(2), effect, box.effect, control);
583 return ValueEffectControl(value, effect, control);
584}
585
586EffectControlLinearizer::ValueEffectControl
587EffectControlLinearizer::LowerChangeBitToTagged(Node* node, Node* effect,
588 Node* control) {
589 Node* value = node->InputAt(0);
590
591 Node* branch = graph()->NewNode(common()->Branch(), value, control);
592
593 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
594 Node* vtrue = jsgraph()->TrueConstant();
595
596 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
597 Node* vfalse = jsgraph()->FalseConstant();
598
599 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
600 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
601 vtrue, vfalse, control);
602
603 return ValueEffectControl(value, effect, control);
604}
605
606EffectControlLinearizer::ValueEffectControl
607EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node,
608 Node* effect,
609 Node* control) {
610 Node* value = node->InputAt(0);
611 value = ChangeInt32ToSmi(value);
612 return ValueEffectControl(value, effect, control);
613}
614
615EffectControlLinearizer::ValueEffectControl
616EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node, Node* effect,
617 Node* control) {
618 Node* value = node->InputAt(0);
619
620 if (machine()->Is64()) {
621 return ValueEffectControl(ChangeInt32ToSmi(value), effect, control);
622 }
623
Ben Murdoch61f157c2016-09-16 13:49:30 +0100624 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value,
625 control);
Ben Murdochc5610432016-08-08 18:44:38 +0100626
Ben Murdoch61f157c2016-09-16 13:49:30 +0100627 Node* ovf = graph()->NewNode(common()->Projection(1), add, control);
Ben Murdochc5610432016-08-08 18:44:38 +0100628 Node* branch =
629 graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control);
630
631 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
632 ValueEffectControl alloc =
633 AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), effect, if_true);
634
635 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100636 Node* vfalse = graph()->NewNode(common()->Projection(0), add, if_false);
Ben Murdochc5610432016-08-08 18:44:38 +0100637
638 Node* merge = graph()->NewNode(common()->Merge(2), alloc.control, if_false);
639 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
640 alloc.value, vfalse, merge);
641 Node* ephi =
642 graph()->NewNode(common()->EffectPhi(2), alloc.effect, effect, merge);
643
644 return ValueEffectControl(phi, ephi, merge);
645}
646
647EffectControlLinearizer::ValueEffectControl
648EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node, Node* effect,
649 Node* control) {
650 Node* value = node->InputAt(0);
651
652 Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value,
653 SmiMaxValueConstant());
654 Node* branch =
655 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
656
657 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
658 Node* vtrue = ChangeUint32ToSmi(value);
659
660 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
661 ValueEffectControl alloc = AllocateHeapNumberWithValue(
662 ChangeUint32ToFloat64(value), effect, if_false);
663
664 Node* merge = graph()->NewNode(common()->Merge(2), if_true, alloc.control);
665 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
666 vtrue, alloc.value, merge);
667 Node* ephi =
668 graph()->NewNode(common()->EffectPhi(2), effect, alloc.effect, merge);
669
670 return ValueEffectControl(phi, ephi, merge);
671}
672
673EffectControlLinearizer::ValueEffectControl
674EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node,
675 Node* effect,
676 Node* control) {
677 Node* value = node->InputAt(0);
678 value = ChangeSmiToInt32(value);
679 return ValueEffectControl(value, effect, control);
680}
681
682EffectControlLinearizer::ValueEffectControl
683EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect,
684 Node* control) {
685 Node* value = node->InputAt(0);
686 value = graph()->NewNode(machine()->WordEqual(), value,
687 jsgraph()->TrueConstant());
688 return ValueEffectControl(value, effect, control);
689}
690
691EffectControlLinearizer::ValueEffectControl
692EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect,
693 Node* control) {
694 Node* value = node->InputAt(0);
695
696 Node* check = ObjectIsSmi(value);
697 Node* branch =
698 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
699
700 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
701 Node* etrue = effect;
702 Node* vtrue = ChangeSmiToInt32(value);
703
704 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
705 Node* efalse = effect;
706 Node* vfalse;
707 {
708 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
709 vfalse = efalse = graph()->NewNode(
710 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
711 efalse, if_false);
712 vfalse = graph()->NewNode(machine()->ChangeFloat64ToInt32(), vfalse);
713 }
714
715 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
716 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
717 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
718 vtrue, vfalse, control);
719
720 return ValueEffectControl(value, effect, control);
721}
722
723EffectControlLinearizer::ValueEffectControl
724EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node, Node* effect,
725 Node* control) {
726 Node* value = node->InputAt(0);
727
728 Node* check = ObjectIsSmi(value);
729 Node* branch =
730 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
731
732 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
733 Node* etrue = effect;
734 Node* vtrue = ChangeSmiToInt32(value);
735
736 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
737 Node* efalse = effect;
738 Node* vfalse;
739 {
740 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
741 vfalse = efalse = graph()->NewNode(
742 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
743 efalse, if_false);
744 vfalse = graph()->NewNode(machine()->ChangeFloat64ToUint32(), vfalse);
745 }
746
747 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
748 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
749 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
750 vtrue, vfalse, control);
751
752 return ValueEffectControl(value, effect, control);
753}
754
755EffectControlLinearizer::ValueEffectControl
756EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node, Node* effect,
757 Node* control) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100758 return LowerTruncateTaggedToFloat64(node, effect, control);
759}
760
761EffectControlLinearizer::ValueEffectControl
762EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node, Node* effect,
763 Node* control) {
Ben Murdochc5610432016-08-08 18:44:38 +0100764 Node* value = node->InputAt(0);
765
766 Node* check = ObjectIsSmi(value);
767 Node* branch =
768 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
769
770 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
771 Node* etrue = effect;
772 Node* vtrue;
773 {
774 vtrue = ChangeSmiToInt32(value);
775 vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue);
776 }
777
778 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
779 Node* efalse = effect;
780 Node* vfalse;
781 {
782 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
783 vfalse = efalse = graph()->NewNode(
784 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
785 efalse, if_false);
786 }
787
788 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
789 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
790 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
791 vtrue, vfalse, control);
792
793 return ValueEffectControl(value, effect, control);
794}
795
796EffectControlLinearizer::ValueEffectControl
Ben Murdoch61f157c2016-09-16 13:49:30 +0100797EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state,
798 Node* effect, Node* control) {
799 Node* index = node->InputAt(0);
800 Node* limit = node->InputAt(1);
801
802 Node* check = graph()->NewNode(machine()->Uint32LessThan(), index, limit);
803 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check,
804 frame_state, effect, control);
805
806 // Make sure the lowered node does not appear in any use lists.
807 node->TrimInputCount(0);
808
809 return ValueEffectControl(index, effect, control);
810}
811
812EffectControlLinearizer::ValueEffectControl
813EffectControlLinearizer::LowerCheckTaggedPointer(Node* node, Node* frame_state,
814 Node* effect, Node* control) {
815 Node* value = node->InputAt(0);
816
817 Node* check = ObjectIsSmi(value);
818 control = effect = graph()->NewNode(common()->DeoptimizeIf(), check,
819 frame_state, effect, control);
820
821 // Make sure the lowered node does not appear in any use lists.
822 node->TrimInputCount(0);
823
824 return ValueEffectControl(value, effect, control);
825}
826
827EffectControlLinearizer::ValueEffectControl
828EffectControlLinearizer::LowerCheckTaggedSigned(Node* node, Node* frame_state,
829 Node* effect, Node* control) {
830 Node* value = node->InputAt(0);
831
832 Node* check = ObjectIsSmi(value);
833 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check,
834 frame_state, effect, control);
835
836 // Make sure the lowered node does not appear in any use lists.
837 node->TrimInputCount(0);
838
839 return ValueEffectControl(value, effect, control);
840}
841
842EffectControlLinearizer::ValueEffectControl
843EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* frame_state,
844 Node* effect, Node* control) {
845 Node* lhs = node->InputAt(0);
846 Node* rhs = node->InputAt(1);
847
848 Node* value =
849 graph()->NewNode(machine()->Int32AddWithOverflow(), lhs, rhs, control);
850
851 Node* check = graph()->NewNode(common()->Projection(1), value, control);
852 control = effect = graph()->NewNode(common()->DeoptimizeIf(), check,
853 frame_state, effect, control);
854
855 value = graph()->NewNode(common()->Projection(0), value, control);
856
857 // Make sure the lowered node does not appear in any use lists.
858 node->TrimInputCount(0);
859
860 return ValueEffectControl(value, effect, control);
861}
862
863EffectControlLinearizer::ValueEffectControl
864EffectControlLinearizer::LowerCheckedInt32Sub(Node* node, Node* frame_state,
865 Node* effect, Node* control) {
866 Node* lhs = node->InputAt(0);
867 Node* rhs = node->InputAt(1);
868
869 Node* value =
870 graph()->NewNode(machine()->Int32SubWithOverflow(), lhs, rhs, control);
871
872 Node* check = graph()->NewNode(common()->Projection(1), value, control);
873 control = effect = graph()->NewNode(common()->DeoptimizeIf(), check,
874 frame_state, effect, control);
875
876 value = graph()->NewNode(common()->Projection(0), value, control);
877
878 // Make sure the lowered node does not appear in any use lists.
879 node->TrimInputCount(0);
880
881 return ValueEffectControl(value, effect, control);
882}
883
884EffectControlLinearizer::ValueEffectControl
885EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
886 Node* frame_state,
887 Node* effect,
888 Node* control) {
889 Node* value = node->InputAt(0);
890 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max());
891 Node* is_safe =
892 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int);
893 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe,
894 frame_state, effect, control);
895
896 // Make sure the lowered node does not appear in any use lists.
897 node->TrimInputCount(0);
898
899 return ValueEffectControl(value, effect, control);
900}
901
902EffectControlLinearizer::ValueEffectControl
903EffectControlLinearizer::BuildCheckedFloat64ToInt32(Node* value,
904 Node* frame_state,
905 Node* effect,
906 Node* control) {
907 Node* value32 = graph()->NewNode(machine()->RoundFloat64ToInt32(), value);
908 Node* check_same = graph()->NewNode(
909 machine()->Float64Equal(), value,
910 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32));
911 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check_same,
912 frame_state, effect, control);
913
914 // Check if {value} is -0.
915 Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32,
916 jsgraph()->Int32Constant(0));
917 Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse),
918 check_zero, control);
919
920 Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero);
921 Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero);
922
923 // In case of 0, we need to check the high bits for the IEEE -0 pattern.
924 Node* check_negative = graph()->NewNode(
925 machine()->Int32LessThan(),
926 graph()->NewNode(machine()->Float64ExtractHighWord32(), value),
927 jsgraph()->Int32Constant(0));
928
929 Node* deopt_minus_zero = graph()->NewNode(
930 common()->DeoptimizeIf(), check_negative, frame_state, effect, if_zero);
931
932 Node* merge =
933 graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero);
934
935 effect =
936 graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect, merge);
937
938 return ValueEffectControl(value32, effect, merge);
939}
940
941EffectControlLinearizer::ValueEffectControl
942EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node,
943 Node* frame_state,
944 Node* effect,
945 Node* control) {
946 Node* value = node->InputAt(0);
947
948 // Make sure the lowered node does not appear in any use lists.
949 node->TrimInputCount(0);
950
951 return BuildCheckedFloat64ToInt32(value, frame_state, effect, control);
952}
953
954EffectControlLinearizer::ValueEffectControl
955EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
956 Node* frame_state,
957 Node* effect,
958 Node* control) {
959 Node* value = node->InputAt(0);
960
961 Node* check = ObjectIsSmi(value);
962 Node* branch =
963 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
964
965 // In the Smi case, just convert to int32.
966 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
967 Node* etrue = effect;
968 Node* vtrue = ChangeSmiToInt32(value);
969
970 // In the non-Smi case, check the heap numberness, load the number and convert
971 // to int32.
972 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
973 Node* efalse = effect;
974 Node* vfalse;
975 {
976 Node* value_map = efalse =
977 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
978 value, efalse, if_false);
979 Node* check = graph()->NewNode(machine()->WordEqual(), value_map,
980 jsgraph()->HeapNumberMapConstant());
981 if_false = efalse = graph()->NewNode(common()->DeoptimizeUnless(), check,
982 frame_state, efalse, if_false);
983 vfalse = efalse = graph()->NewNode(
984 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
985 efalse, if_false);
986 ValueEffectControl state =
987 BuildCheckedFloat64ToInt32(vfalse, frame_state, efalse, if_false);
988 if_false = state.control;
989 efalse = state.effect;
990 vfalse = state.value;
991 }
992
993 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
994 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
995 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
996 vtrue, vfalse, control);
997
998 // Make sure the lowered node does not appear in any use lists.
999 node->TrimInputCount(0);
1000
1001 return ValueEffectControl(value, effect, control);
1002}
1003
1004EffectControlLinearizer::ValueEffectControl
1005EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
1006 Node* value, Node* frame_state, Node* effect, Node* control) {
1007 Node* value_map = effect = graph()->NewNode(
1008 simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
1009 Node* check_number = graph()->NewNode(machine()->WordEqual(), value_map,
1010 jsgraph()->HeapNumberMapConstant());
1011
1012 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
1013 check_number, control);
1014
1015 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1016 Node* etrue = effect;
1017
1018 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1019 // For oddballs also contain the numeric value, let us just check that
1020 // we have an oddball here.
1021 Node* efalse = effect;
1022 Node* instance_type = efalse = graph()->NewNode(
1023 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
1024 efalse, if_false);
1025 Node* check_oddball =
1026 graph()->NewNode(machine()->Word32Equal(), instance_type,
1027 jsgraph()->Int32Constant(ODDBALL_TYPE));
1028 if_false = efalse =
1029 graph()->NewNode(common()->DeoptimizeUnless(), check_oddball, frame_state,
1030 efalse, if_false);
1031 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1032
1033 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1034 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1035
1036 Node* result = effect = graph()->NewNode(
1037 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1038 effect, control);
1039 return ValueEffectControl(result, effect, control);
1040}
1041
1042EffectControlLinearizer::ValueEffectControl
1043EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
1044 Node* frame_state,
1045 Node* effect,
1046 Node* control) {
1047 Node* value = node->InputAt(0);
1048
1049 Node* check = ObjectIsSmi(value);
1050 Node* branch =
1051 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1052
1053 // In the Smi case, just convert to int32 and then float64.
1054 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1055 Node* etrue = effect;
1056 Node* vtrue = ChangeSmiToInt32(value);
1057 vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue);
1058
1059 // Otherwise, check heap numberness and load the number.
1060 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1061 ValueEffectControl number_state = BuildCheckedHeapNumberOrOddballToFloat64(
1062 value, frame_state, effect, if_false);
1063
1064 Node* merge =
1065 graph()->NewNode(common()->Merge(2), if_true, number_state.control);
1066 Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue,
1067 number_state.effect, merge);
1068 Node* result =
1069 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), vtrue,
1070 number_state.value, merge);
1071
1072 // Make sure the lowered node does not appear in any use lists.
1073 node->TrimInputCount(0);
1074
1075 return ValueEffectControl(result, effect_phi, merge);
1076}
1077
1078EffectControlLinearizer::ValueEffectControl
Ben Murdochc5610432016-08-08 18:44:38 +01001079EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect,
1080 Node* control) {
1081 Node* value = node->InputAt(0);
1082
1083 Node* check = ObjectIsSmi(value);
1084 Node* branch =
1085 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1086
1087 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1088 Node* etrue = effect;
1089 Node* vtrue = ChangeSmiToInt32(value);
1090
1091 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1092 Node* efalse = effect;
1093 Node* vfalse;
1094 {
1095 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1096 vfalse = efalse = graph()->NewNode(
1097 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1098 efalse, if_false);
1099 vfalse = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse);
1100 }
1101
1102 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1103 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1104 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1105 vtrue, vfalse, control);
1106
1107 return ValueEffectControl(value, effect, control);
1108}
1109
1110EffectControlLinearizer::ValueEffectControl
1111EffectControlLinearizer::LowerObjectIsCallable(Node* node, Node* effect,
1112 Node* control) {
1113 Node* value = node->InputAt(0);
1114
1115 Node* check = ObjectIsSmi(value);
1116 Node* branch =
1117 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
1118
1119 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1120 Node* etrue = effect;
1121 Node* vtrue = jsgraph()->Int32Constant(0);
1122
1123 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1124 Node* efalse = effect;
1125 Node* vfalse;
1126 {
1127 Node* value_map = efalse =
1128 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
1129 value, efalse, if_false);
1130 Node* value_bit_field = efalse = graph()->NewNode(
1131 simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
1132 efalse, if_false);
1133 vfalse = graph()->NewNode(
1134 machine()->Word32Equal(),
1135 jsgraph()->Int32Constant(1 << Map::kIsCallable),
1136 graph()->NewNode(
1137 machine()->Word32And(), value_bit_field,
1138 jsgraph()->Int32Constant((1 << Map::kIsCallable) |
1139 (1 << Map::kIsUndetectable))));
1140 }
1141
1142 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1143 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1144 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
1145 vfalse, control);
1146
1147 return ValueEffectControl(value, effect, control);
1148}
1149
1150EffectControlLinearizer::ValueEffectControl
1151EffectControlLinearizer::LowerObjectIsNumber(Node* node, Node* effect,
1152 Node* control) {
1153 Node* value = node->InputAt(0);
1154
1155 Node* check = ObjectIsSmi(value);
1156 Node* branch = graph()->NewNode(common()->Branch(), check, control);
1157
1158 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1159 Node* etrue = effect;
1160 Node* vtrue = jsgraph()->Int32Constant(1);
1161
1162 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1163 Node* efalse = effect;
1164 Node* vfalse;
1165 {
1166 Node* value_map = efalse =
1167 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
1168 value, efalse, if_false);
1169 vfalse = graph()->NewNode(machine()->WordEqual(), value_map,
1170 jsgraph()->HeapNumberMapConstant());
1171 }
1172
1173 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1174 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1175 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
1176 vfalse, control);
1177
1178 return ValueEffectControl(value, effect, control);
1179}
1180
1181EffectControlLinearizer::ValueEffectControl
1182EffectControlLinearizer::LowerObjectIsReceiver(Node* node, Node* effect,
1183 Node* control) {
1184 Node* value = node->InputAt(0);
1185
1186 Node* check = ObjectIsSmi(value);
1187 Node* branch =
1188 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
1189
1190 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1191 Node* etrue = effect;
1192 Node* vtrue = jsgraph()->Int32Constant(0);
1193
1194 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1195 Node* efalse = effect;
1196 Node* vfalse;
1197 {
1198 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
1199 Node* value_map = efalse =
1200 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
1201 value, efalse, if_false);
1202 Node* value_instance_type = efalse = graph()->NewNode(
1203 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
1204 efalse, if_false);
1205 vfalse = graph()->NewNode(machine()->Uint32LessThanOrEqual(),
1206 jsgraph()->Uint32Constant(FIRST_JS_RECEIVER_TYPE),
1207 value_instance_type);
1208 }
1209
1210 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1211 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1212 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
1213 vfalse, control);
1214
1215 return ValueEffectControl(value, effect, control);
1216}
1217
1218EffectControlLinearizer::ValueEffectControl
1219EffectControlLinearizer::LowerObjectIsSmi(Node* node, Node* effect,
1220 Node* control) {
1221 Node* value = node->InputAt(0);
1222 value = ObjectIsSmi(value);
1223 return ValueEffectControl(value, effect, control);
1224}
1225
1226EffectControlLinearizer::ValueEffectControl
1227EffectControlLinearizer::LowerObjectIsString(Node* node, Node* effect,
1228 Node* control) {
1229 Node* value = node->InputAt(0);
1230
1231 Node* check = ObjectIsSmi(value);
1232 Node* branch =
1233 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
1234
1235 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1236 Node* etrue = effect;
1237 Node* vtrue = jsgraph()->Int32Constant(0);
1238
1239 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1240 Node* efalse = effect;
1241 Node* vfalse;
1242 {
1243 Node* value_map = efalse =
1244 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
1245 value, efalse, if_false);
1246 Node* value_instance_type = efalse = graph()->NewNode(
1247 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
1248 efalse, if_false);
1249 vfalse = graph()->NewNode(machine()->Uint32LessThan(), value_instance_type,
1250 jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE));
1251 }
1252
1253 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1254 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1255 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
1256 vfalse, control);
1257
1258 return ValueEffectControl(value, effect, control);
1259}
1260
1261EffectControlLinearizer::ValueEffectControl
1262EffectControlLinearizer::LowerObjectIsUndetectable(Node* node, Node* effect,
1263 Node* control) {
1264 Node* value = node->InputAt(0);
1265
1266 Node* check = ObjectIsSmi(value);
1267 Node* branch =
1268 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
1269
1270 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1271 Node* etrue = effect;
1272 Node* vtrue = jsgraph()->Int32Constant(0);
1273
1274 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1275 Node* efalse = effect;
1276 Node* vfalse;
1277 {
1278 Node* value_map = efalse =
1279 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
1280 value, efalse, if_false);
1281 Node* value_bit_field = efalse = graph()->NewNode(
1282 simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
1283 efalse, if_false);
1284 vfalse = graph()->NewNode(
1285 machine()->Word32Equal(),
1286 graph()->NewNode(
1287 machine()->Word32Equal(), jsgraph()->Int32Constant(0),
1288 graph()->NewNode(
1289 machine()->Word32And(), value_bit_field,
1290 jsgraph()->Int32Constant(1 << Map::kIsUndetectable))),
1291 jsgraph()->Int32Constant(0));
1292 }
1293
1294 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1295 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1296 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
1297 vfalse, control);
1298
1299 return ValueEffectControl(value, effect, control);
1300}
1301
1302EffectControlLinearizer::ValueEffectControl
Ben Murdoch61f157c2016-09-16 13:49:30 +01001303EffectControlLinearizer::LowerStringFromCharCode(Node* node, Node* effect,
1304 Node* control) {
1305 Node* value = node->InputAt(0);
1306
1307 // Compute the character code.
1308 Node* code =
1309 graph()->NewNode(machine()->Word32And(), value,
1310 jsgraph()->Int32Constant(String::kMaxUtf16CodeUnit));
1311
1312 // Check if the {code} is a one-byte char code.
1313 Node* check0 =
1314 graph()->NewNode(machine()->Int32LessThanOrEqual(), code,
1315 jsgraph()->Int32Constant(String::kMaxOneByteCharCode));
1316 Node* branch0 =
1317 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
1318
1319 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1320 Node* etrue0 = effect;
1321 Node* vtrue0;
1322 {
1323 // Load the isolate wide single character string cache.
1324 Node* cache =
1325 jsgraph()->HeapConstant(factory()->single_character_string_cache());
1326
1327 // Compute the {cache} index for {code}.
1328 Node* index =
1329 machine()->Is32() ? code : graph()->NewNode(
1330 machine()->ChangeUint32ToUint64(), code);
1331
1332 // Check if we have an entry for the {code} in the single character string
1333 // cache already.
1334 Node* entry = etrue0 = graph()->NewNode(
1335 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache,
1336 index, etrue0, if_true0);
1337
1338 Node* check1 = graph()->NewNode(machine()->WordEqual(), entry,
1339 jsgraph()->UndefinedConstant());
1340 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1341 check1, if_true0);
1342
1343 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1344 Node* etrue1 = etrue0;
1345 Node* vtrue1;
1346 {
1347 // Allocate a new SeqOneByteString for {code}.
1348 vtrue1 = etrue1 = graph()->NewNode(
1349 simplified()->Allocate(NOT_TENURED),
1350 jsgraph()->Int32Constant(SeqOneByteString::SizeFor(1)), etrue1,
1351 if_true1);
1352 etrue1 = graph()->NewNode(
1353 simplified()->StoreField(AccessBuilder::ForMap()), vtrue1,
1354 jsgraph()->HeapConstant(factory()->one_byte_string_map()), etrue1,
1355 if_true1);
1356 etrue1 = graph()->NewNode(
1357 simplified()->StoreField(AccessBuilder::ForNameHashField()), vtrue1,
1358 jsgraph()->IntPtrConstant(Name::kEmptyHashField), etrue1, if_true1);
1359 etrue1 = graph()->NewNode(
1360 simplified()->StoreField(AccessBuilder::ForStringLength()), vtrue1,
1361 jsgraph()->SmiConstant(1), etrue1, if_true1);
1362 etrue1 = graph()->NewNode(
1363 machine()->Store(StoreRepresentation(MachineRepresentation::kWord8,
1364 kNoWriteBarrier)),
1365 vtrue1, jsgraph()->IntPtrConstant(SeqOneByteString::kHeaderSize -
1366 kHeapObjectTag),
1367 code, etrue1, if_true1);
1368
1369 // Remember it in the {cache}.
1370 etrue1 = graph()->NewNode(
1371 simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()),
1372 cache, index, vtrue1, etrue1, if_true1);
1373 }
1374
1375 // Use the {entry} from the {cache}.
1376 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1377 Node* efalse1 = etrue0;
1378 Node* vfalse1 = entry;
1379
1380 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1381 etrue0 =
1382 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
1383 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
1384 vtrue1, vfalse1, if_true0);
1385 }
1386
1387 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1388 Node* efalse0 = effect;
1389 Node* vfalse0;
1390 {
1391 // Allocate a new SeqTwoByteString for {code}.
1392 vfalse0 = efalse0 =
1393 graph()->NewNode(simplified()->Allocate(NOT_TENURED),
1394 jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(1)),
1395 efalse0, if_false0);
1396 efalse0 = graph()->NewNode(
1397 simplified()->StoreField(AccessBuilder::ForMap()), vfalse0,
1398 jsgraph()->HeapConstant(factory()->string_map()), efalse0, if_false0);
1399 efalse0 = graph()->NewNode(
1400 simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse0,
1401 jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse0, if_false0);
1402 efalse0 = graph()->NewNode(
1403 simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse0,
1404 jsgraph()->SmiConstant(1), efalse0, if_false0);
1405 efalse0 = graph()->NewNode(
1406 machine()->Store(StoreRepresentation(MachineRepresentation::kWord16,
1407 kNoWriteBarrier)),
1408 vfalse0, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize -
1409 kHeapObjectTag),
1410 code, efalse0, if_false0);
1411 }
1412
1413 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1414 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1415 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
1416 vtrue0, vfalse0, control);
1417
1418 return ValueEffectControl(value, effect, control);
1419}
1420
1421EffectControlLinearizer::ValueEffectControl
1422EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, Node* frame_state,
1423 Node* effect, Node* control) {
1424 // If we reach this point w/o eliminating the {node} that's marked
1425 // with allow-return-hole, we cannot do anything, so just deoptimize
1426 // in case of the hole NaN (similar to Crankshaft).
1427 Node* value = node->InputAt(0);
1428 Node* check = graph()->NewNode(
1429 machine()->Word32Equal(),
1430 graph()->NewNode(machine()->Float64ExtractHighWord32(), value),
1431 jsgraph()->Int32Constant(kHoleNanUpper32));
1432 control = effect = graph()->NewNode(common()->DeoptimizeIf(), check,
1433 frame_state, effect, control);
1434
1435 // Make sure the lowered node does not appear in any use lists.
1436 node->TrimInputCount(0);
1437
1438 return ValueEffectControl(value, effect, control);
1439}
1440
1441EffectControlLinearizer::ValueEffectControl
1442EffectControlLinearizer::LowerCheckTaggedHole(Node* node, Node* frame_state,
1443 Node* effect, Node* control) {
1444 CheckTaggedHoleMode mode = CheckTaggedHoleModeOf(node->op());
1445 Node* value = node->InputAt(0);
1446 Node* check = graph()->NewNode(machine()->WordEqual(), value,
1447 jsgraph()->TheHoleConstant());
1448 switch (mode) {
1449 case CheckTaggedHoleMode::kConvertHoleToUndefined:
1450 value = graph()->NewNode(
1451 common()->Select(MachineRepresentation::kTagged, BranchHint::kFalse),
1452 check, jsgraph()->UndefinedConstant(), value);
1453 break;
1454 case CheckTaggedHoleMode::kNeverReturnHole:
1455 control = effect = graph()->NewNode(common()->DeoptimizeIf(), check,
1456 frame_state, effect, control);
1457 break;
1458 }
1459
1460 // Make sure the lowered node does not appear in any use lists.
1461 node->TrimInputCount(0);
1462
1463 return ValueEffectControl(value, effect, control);
1464}
1465
1466EffectControlLinearizer::ValueEffectControl
Ben Murdochc5610432016-08-08 18:44:38 +01001467EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect,
1468 Node* control) {
1469 Node* result = effect = graph()->NewNode(
1470 simplified()->Allocate(NOT_TENURED),
1471 jsgraph()->Int32Constant(HeapNumber::kSize), effect, control);
1472 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
1473 result, jsgraph()->HeapNumberMapConstant(), effect,
1474 control);
1475 effect = graph()->NewNode(
1476 simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), result,
1477 value, effect, control);
1478 return ValueEffectControl(result, effect, control);
1479}
1480
1481Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) {
1482 if (machine()->Is64()) {
1483 value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value);
1484 }
1485 return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
1486}
1487
1488Node* EffectControlLinearizer::ChangeUint32ToSmi(Node* value) {
1489 if (machine()->Is64()) {
1490 value = graph()->NewNode(machine()->ChangeUint32ToUint64(), value);
1491 }
1492 return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
1493}
1494
1495Node* EffectControlLinearizer::ChangeInt32ToFloat64(Node* value) {
1496 return graph()->NewNode(machine()->ChangeInt32ToFloat64(), value);
1497}
1498
1499Node* EffectControlLinearizer::ChangeUint32ToFloat64(Node* value) {
1500 return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value);
1501}
1502
1503Node* EffectControlLinearizer::ChangeSmiToInt32(Node* value) {
1504 value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
1505 if (machine()->Is64()) {
1506 value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value);
1507 }
1508 return value;
1509}
Ben Murdochc5610432016-08-08 18:44:38 +01001510Node* EffectControlLinearizer::ObjectIsSmi(Node* value) {
1511 return graph()->NewNode(
1512 machine()->WordEqual(),
1513 graph()->NewNode(machine()->WordAnd(), value,
1514 jsgraph()->IntPtrConstant(kSmiTagMask)),
1515 jsgraph()->IntPtrConstant(kSmiTag));
1516}
1517
1518Node* EffectControlLinearizer::SmiMaxValueConstant() {
1519 return jsgraph()->Int32Constant(Smi::kMaxValue);
1520}
1521
1522Node* EffectControlLinearizer::SmiShiftBitsConstant() {
1523 return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize);
1524}
1525
Ben Murdoch61f157c2016-09-16 13:49:30 +01001526EffectControlLinearizer::ValueEffectControl
1527EffectControlLinearizer::LowerPlainPrimitiveToNumber(Node* node, Node* effect,
1528 Node* control) {
1529 Node* value = node->InputAt(0);
1530 Node* result = effect =
1531 graph()->NewNode(ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(),
1532 value, jsgraph()->NoContextConstant(), effect, control);
1533 return ValueEffectControl(result, effect, control);
1534}
1535
1536EffectControlLinearizer::ValueEffectControl
1537EffectControlLinearizer::LowerPlainPrimitiveToWord32(Node* node, Node* effect,
1538 Node* control) {
1539 Node* value = node->InputAt(0);
1540
1541 Node* check0 = ObjectIsSmi(value);
1542 Node* branch0 =
1543 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
1544
1545 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1546 Node* etrue0 = effect;
1547 Node* vtrue0 = ChangeSmiToInt32(value);
1548
1549 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1550 Node* efalse0 = effect;
1551 Node* vfalse0;
1552 {
1553 vfalse0 = efalse0 = graph()->NewNode(
1554 ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value,
1555 jsgraph()->NoContextConstant(), efalse0, if_false0);
1556
1557 Node* check1 = ObjectIsSmi(vfalse0);
1558 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
1559
1560 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1561 Node* etrue1 = efalse0;
1562 Node* vtrue1 = ChangeSmiToInt32(vfalse0);
1563
1564 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1565 Node* efalse1 = efalse0;
1566 Node* vfalse1;
1567 {
1568 vfalse1 = efalse1 = graph()->NewNode(
1569 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
1570 efalse1, if_false1);
1571 vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1);
1572 }
1573
1574 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1575 efalse0 =
1576 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
1577 vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1578 vtrue1, vfalse1, if_false0);
1579 }
1580
1581 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1582 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1583 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1584 vtrue0, vfalse0, control);
1585 return ValueEffectControl(value, effect, control);
1586}
1587
1588EffectControlLinearizer::ValueEffectControl
1589EffectControlLinearizer::LowerPlainPrimitiveToFloat64(Node* node, Node* effect,
1590 Node* control) {
1591 Node* value = node->InputAt(0);
1592
1593 Node* check0 = ObjectIsSmi(value);
1594 Node* branch0 =
1595 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
1596
1597 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1598 Node* etrue0 = effect;
1599 Node* vtrue0;
1600 {
1601 vtrue0 = ChangeSmiToInt32(value);
1602 vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
1603 }
1604
1605 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1606 Node* efalse0 = effect;
1607 Node* vfalse0;
1608 {
1609 vfalse0 = efalse0 = graph()->NewNode(
1610 ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value,
1611 jsgraph()->NoContextConstant(), efalse0, if_false0);
1612
1613 Node* check1 = ObjectIsSmi(vfalse0);
1614 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
1615
1616 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1617 Node* etrue1 = efalse0;
1618 Node* vtrue1;
1619 {
1620 vtrue1 = ChangeSmiToInt32(vfalse0);
1621 vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
1622 }
1623
1624 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1625 Node* efalse1 = efalse0;
1626 Node* vfalse1;
1627 {
1628 vfalse1 = efalse1 = graph()->NewNode(
1629 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
1630 efalse1, if_false1);
1631 }
1632
1633 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1634 efalse0 =
1635 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
1636 vfalse0 =
1637 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1638 vtrue1, vfalse1, if_false0);
1639 }
1640
1641 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1642 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1643 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1644 vtrue0, vfalse0, control);
1645 return ValueEffectControl(value, effect, control);
1646}
1647
1648Factory* EffectControlLinearizer::factory() const {
1649 return isolate()->factory();
1650}
1651
1652Isolate* EffectControlLinearizer::isolate() const {
1653 return jsgraph()->isolate();
1654}
1655
1656Operator const* EffectControlLinearizer::ToNumberOperator() {
1657 if (!to_number_operator_.is_set()) {
1658 Callable callable = CodeFactory::ToNumber(isolate());
1659 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
1660 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
1661 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
1662 Operator::kNoThrow);
1663 to_number_operator_.set(common()->Call(desc));
1664 }
1665 return to_number_operator_.get();
1666}
1667
Ben Murdochc5610432016-08-08 18:44:38 +01001668} // namespace compiler
1669} // namespace internal
1670} // namespace v8