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/effect-control-linearizer.h"
6 
7 #include "src/code-factory.h"
8 #include "src/compiler/access-builder.h"
9 #include "src/compiler/compiler-source-position-table.h"
10 #include "src/compiler/js-graph.h"
11 #include "src/compiler/linkage.h"
12 #include "src/compiler/node-matchers.h"
13 #include "src/compiler/node-properties.h"
14 #include "src/compiler/node.h"
15 #include "src/compiler/schedule.h"
16 
17 namespace v8 {
18 namespace internal {
19 namespace compiler {
20 
EffectControlLinearizer(JSGraph * js_graph,Schedule * schedule,Zone * temp_zone,SourcePositionTable * source_positions)21 EffectControlLinearizer::EffectControlLinearizer(
22     JSGraph* js_graph, Schedule* schedule, Zone* temp_zone,
23     SourcePositionTable* source_positions)
24     : js_graph_(js_graph),
25       schedule_(schedule),
26       temp_zone_(temp_zone),
27       source_positions_(source_positions) {}
28 
graph() const29 Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); }
common() const30 CommonOperatorBuilder* EffectControlLinearizer::common() const {
31   return js_graph_->common();
32 }
simplified() const33 SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const {
34   return js_graph_->simplified();
35 }
machine() const36 MachineOperatorBuilder* EffectControlLinearizer::machine() const {
37   return js_graph_->machine();
38 }
39 
40 namespace {
41 
42 struct BlockEffectControlData {
43   Node* current_effect = nullptr;       // New effect.
44   Node* current_control = nullptr;      // New control.
45   Node* current_frame_state = nullptr;  // New frame state.
46 };
47 
48 class BlockEffectControlMap {
49  public:
BlockEffectControlMap(Zone * temp_zone)50   explicit BlockEffectControlMap(Zone* temp_zone) : map_(temp_zone) {}
51 
For(BasicBlock * from,BasicBlock * to)52   BlockEffectControlData& For(BasicBlock* from, BasicBlock* to) {
53     return map_[std::make_pair(from->rpo_number(), to->rpo_number())];
54   }
55 
For(BasicBlock * from,BasicBlock * to) const56   const BlockEffectControlData& For(BasicBlock* from, BasicBlock* to) const {
57     return map_.at(std::make_pair(from->rpo_number(), to->rpo_number()));
58   }
59 
60  private:
61   typedef std::pair<int32_t, int32_t> Key;
62   typedef ZoneMap<Key, BlockEffectControlData> Map;
63 
64   Map map_;
65 };
66 
67 // Effect phis that need to be updated after the first pass.
68 struct PendingEffectPhi {
69   Node* effect_phi;
70   BasicBlock* block;
71 
PendingEffectPhiv8::internal::compiler::__anon37f087a00111::PendingEffectPhi72   PendingEffectPhi(Node* effect_phi, BasicBlock* block)
73       : effect_phi(effect_phi), block(block) {}
74 };
75 
UpdateEffectPhi(Node * node,BasicBlock * block,BlockEffectControlMap * block_effects)76 void UpdateEffectPhi(Node* node, BasicBlock* block,
77                      BlockEffectControlMap* block_effects) {
78   // Update all inputs to an effect phi with the effects from the given
79   // block->effect map.
80   DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
81   DCHECK_EQ(static_cast<size_t>(node->op()->EffectInputCount()),
82             block->PredecessorCount());
83   for (int i = 0; i < node->op()->EffectInputCount(); i++) {
84     Node* input = node->InputAt(i);
85     BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
86     const BlockEffectControlData& block_effect =
87         block_effects->For(predecessor, block);
88     if (input != block_effect.current_effect) {
89       node->ReplaceInput(i, block_effect.current_effect);
90     }
91   }
92 }
93 
UpdateBlockControl(BasicBlock * block,BlockEffectControlMap * block_effects)94 void UpdateBlockControl(BasicBlock* block,
95                         BlockEffectControlMap* block_effects) {
96   Node* control = block->NodeAt(0);
97   DCHECK(NodeProperties::IsControl(control));
98 
99   // Do not rewire the end node.
100   if (control->opcode() == IrOpcode::kEnd) return;
101 
102   // Update all inputs to the given control node with the correct control.
103   DCHECK(control->opcode() == IrOpcode::kMerge ||
104          static_cast<size_t>(control->op()->ControlInputCount()) ==
105              block->PredecessorCount());
106   if (static_cast<size_t>(control->op()->ControlInputCount()) !=
107       block->PredecessorCount()) {
108     return;  // We already re-wired the control inputs of this node.
109   }
110   for (int i = 0; i < control->op()->ControlInputCount(); i++) {
111     Node* input = NodeProperties::GetControlInput(control, i);
112     BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
113     const BlockEffectControlData& block_effect =
114         block_effects->For(predecessor, block);
115     if (input != block_effect.current_control) {
116       NodeProperties::ReplaceControlInput(control, block_effect.current_control,
117                                           i);
118     }
119   }
120 }
121 
HasIncomingBackEdges(BasicBlock * block)122 bool HasIncomingBackEdges(BasicBlock* block) {
123   for (BasicBlock* pred : block->predecessors()) {
124     if (pred->rpo_number() >= block->rpo_number()) {
125       return true;
126     }
127   }
128   return false;
129 }
130 
RemoveRegionNode(Node * node)131 void RemoveRegionNode(Node* node) {
132   DCHECK(IrOpcode::kFinishRegion == node->opcode() ||
133          IrOpcode::kBeginRegion == node->opcode());
134   // Update the value/context uses to the value input of the finish node and
135   // the effect uses to the effect input.
136   for (Edge edge : node->use_edges()) {
137     DCHECK(!edge.from()->IsDead());
138     if (NodeProperties::IsEffectEdge(edge)) {
139       edge.UpdateTo(NodeProperties::GetEffectInput(node));
140     } else {
141       DCHECK(!NodeProperties::IsControlEdge(edge));
142       DCHECK(!NodeProperties::IsFrameStateEdge(edge));
143       edge.UpdateTo(node->InputAt(0));
144     }
145   }
146   node->Kill();
147 }
148 
TryCloneBranch(Node * node,BasicBlock * block,Graph * graph,CommonOperatorBuilder * common,BlockEffectControlMap * block_effects,SourcePositionTable * source_positions)149 void TryCloneBranch(Node* node, BasicBlock* block, Graph* graph,
150                     CommonOperatorBuilder* common,
151                     BlockEffectControlMap* block_effects,
152                     SourcePositionTable* source_positions) {
153   DCHECK_EQ(IrOpcode::kBranch, node->opcode());
154 
155   // This optimization is a special case of (super)block cloning. It takes an
156   // input graph as shown below and clones the Branch node for every predecessor
157   // to the Merge, essentially removing the Merge completely. This avoids
158   // materializing the bit for the Phi and may offer potential for further
159   // branch folding optimizations (i.e. because one or more inputs to the Phi is
160   // a constant). Note that there may be more Phi nodes hanging off the Merge,
161   // but we can only a certain subset of them currently (actually only Phi and
162   // EffectPhi nodes whose uses have either the IfTrue or IfFalse as control
163   // input).
164 
165   //   Control1 ... ControlN
166   //      ^            ^
167   //      |            |   Cond1 ... CondN
168   //      +----+  +----+     ^         ^
169   //           |  |          |         |
170   //           |  |     +----+         |
171   //          Merge<--+ | +------------+
172   //            ^      \|/
173   //            |      Phi
174   //            |       |
175   //          Branch----+
176   //            ^
177   //            |
178   //      +-----+-----+
179   //      |           |
180   //    IfTrue     IfFalse
181   //      ^           ^
182   //      |           |
183 
184   // The resulting graph (modulo the Phi and EffectPhi nodes) looks like this:
185 
186   // Control1 Cond1 ... ControlN CondN
187   //    ^      ^           ^      ^
188   //    \      /           \      /
189   //     Branch     ...     Branch
190   //       ^                  ^
191   //       |                  |
192   //   +---+---+          +---+----+
193   //   |       |          |        |
194   // IfTrue IfFalse ... IfTrue  IfFalse
195   //   ^       ^          ^        ^
196   //   |       |          |        |
197   //   +--+ +-------------+        |
198   //      | |  +--------------+ +--+
199   //      | |                 | |
200   //     Merge               Merge
201   //       ^                   ^
202   //       |                   |
203 
204   SourcePositionTable::Scope scope(source_positions,
205                                    source_positions->GetSourcePosition(node));
206   Node* branch = node;
207   Node* cond = NodeProperties::GetValueInput(branch, 0);
208   if (!cond->OwnedBy(branch) || cond->opcode() != IrOpcode::kPhi) return;
209   Node* merge = NodeProperties::GetControlInput(branch);
210   if (merge->opcode() != IrOpcode::kMerge ||
211       NodeProperties::GetControlInput(cond) != merge) {
212     return;
213   }
214   // Grab the IfTrue/IfFalse projections of the Branch.
215   BranchMatcher matcher(branch);
216   // Check/collect other Phi/EffectPhi nodes hanging off the Merge.
217   NodeVector phis(graph->zone());
218   for (Node* const use : merge->uses()) {
219     if (use == branch || use == cond) continue;
220     // We cannot currently deal with non-Phi/EffectPhi nodes hanging off the
221     // Merge. Ideally, we would just clone the nodes (and everything that
222     // depends on it to some distant join point), but that requires knowledge
223     // about dominance/post-dominance.
224     if (!NodeProperties::IsPhi(use)) return;
225     for (Edge edge : use->use_edges()) {
226       // Right now we can only handle Phi/EffectPhi nodes whose uses are
227       // directly control-dependend on either the IfTrue or the IfFalse
228       // successor, because we know exactly how to update those uses.
229       if (edge.from()->op()->ControlInputCount() != 1) return;
230       Node* control = NodeProperties::GetControlInput(edge.from());
231       if (NodeProperties::IsPhi(edge.from())) {
232         control = NodeProperties::GetControlInput(control, edge.index());
233       }
234       if (control != matcher.IfTrue() && control != matcher.IfFalse()) return;
235     }
236     phis.push_back(use);
237   }
238   BranchHint const hint = BranchHintOf(branch->op());
239   int const input_count = merge->op()->ControlInputCount();
240   DCHECK_LE(1, input_count);
241   Node** const inputs = graph->zone()->NewArray<Node*>(2 * input_count);
242   Node** const merge_true_inputs = &inputs[0];
243   Node** const merge_false_inputs = &inputs[input_count];
244   for (int index = 0; index < input_count; ++index) {
245     Node* cond1 = NodeProperties::GetValueInput(cond, index);
246     Node* control1 = NodeProperties::GetControlInput(merge, index);
247     Node* branch1 = graph->NewNode(common->Branch(hint), cond1, control1);
248     merge_true_inputs[index] = graph->NewNode(common->IfTrue(), branch1);
249     merge_false_inputs[index] = graph->NewNode(common->IfFalse(), branch1);
250   }
251   Node* const merge_true = matcher.IfTrue();
252   Node* const merge_false = matcher.IfFalse();
253   merge_true->TrimInputCount(0);
254   merge_false->TrimInputCount(0);
255   for (int i = 0; i < input_count; ++i) {
256     merge_true->AppendInput(graph->zone(), merge_true_inputs[i]);
257     merge_false->AppendInput(graph->zone(), merge_false_inputs[i]);
258   }
259   DCHECK_EQ(2u, block->SuccessorCount());
260   NodeProperties::ChangeOp(matcher.IfTrue(), common->Merge(input_count));
261   NodeProperties::ChangeOp(matcher.IfFalse(), common->Merge(input_count));
262   int const true_index =
263       block->SuccessorAt(0)->NodeAt(0) == matcher.IfTrue() ? 0 : 1;
264   BlockEffectControlData* true_block_data =
265       &block_effects->For(block, block->SuccessorAt(true_index));
266   BlockEffectControlData* false_block_data =
267       &block_effects->For(block, block->SuccessorAt(true_index ^ 1));
268   for (Node* const phi : phis) {
269     for (int index = 0; index < input_count; ++index) {
270       inputs[index] = phi->InputAt(index);
271     }
272     inputs[input_count] = merge_true;
273     Node* phi_true = graph->NewNode(phi->op(), input_count + 1, inputs);
274     inputs[input_count] = merge_false;
275     Node* phi_false = graph->NewNode(phi->op(), input_count + 1, inputs);
276     if (phi->UseCount() == 0) {
277       DCHECK_EQ(phi->opcode(), IrOpcode::kEffectPhi);
278     } else {
279       for (Edge edge : phi->use_edges()) {
280         Node* control = NodeProperties::GetControlInput(edge.from());
281         if (NodeProperties::IsPhi(edge.from())) {
282           control = NodeProperties::GetControlInput(control, edge.index());
283         }
284         DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse());
285         edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false);
286       }
287     }
288     if (phi->opcode() == IrOpcode::kEffectPhi) {
289       true_block_data->current_effect = phi_true;
290       false_block_data->current_effect = phi_false;
291     }
292     phi->Kill();
293   }
294   // Fix up IfTrue and IfFalse and kill all dead nodes.
295   if (branch == block->control_input()) {
296     true_block_data->current_control = merge_true;
297     false_block_data->current_control = merge_false;
298   }
299   branch->Kill();
300   cond->Kill();
301   merge->Kill();
302 }
303 }  // namespace
304 
Run()305 void EffectControlLinearizer::Run() {
306   BlockEffectControlMap block_effects(temp_zone());
307   ZoneVector<PendingEffectPhi> pending_effect_phis(temp_zone());
308   ZoneVector<BasicBlock*> pending_block_controls(temp_zone());
309   NodeVector inputs_buffer(temp_zone());
310 
311   for (BasicBlock* block : *(schedule()->rpo_order())) {
312     size_t instr = 0;
313 
314     // The control node should be the first.
315     Node* control = block->NodeAt(instr);
316     DCHECK(NodeProperties::IsControl(control));
317     // Update the control inputs.
318     if (HasIncomingBackEdges(block)) {
319       // If there are back edges, we need to update later because we have not
320       // computed the control yet. This should only happen for loops.
321       DCHECK_EQ(IrOpcode::kLoop, control->opcode());
322       pending_block_controls.push_back(block);
323     } else {
324       // If there are no back edges, we can update now.
325       UpdateBlockControl(block, &block_effects);
326     }
327     instr++;
328 
329     // Iterate over the phis and update the effect phis.
330     Node* effect = nullptr;
331     Node* terminate = nullptr;
332     for (; instr < block->NodeCount(); instr++) {
333       Node* node = block->NodeAt(instr);
334       // Only go through the phis and effect phis.
335       if (node->opcode() == IrOpcode::kEffectPhi) {
336         // There should be at most one effect phi in a block.
337         DCHECK_NULL(effect);
338         // IfException blocks should not have effect phis.
339         DCHECK_NE(IrOpcode::kIfException, control->opcode());
340         effect = node;
341 
342         // Make sure we update the inputs to the incoming blocks' effects.
343         if (HasIncomingBackEdges(block)) {
344           // In case of loops, we do not update the effect phi immediately
345           // because the back predecessor has not been handled yet. We just
346           // record the effect phi for later processing.
347           pending_effect_phis.push_back(PendingEffectPhi(node, block));
348         } else {
349           UpdateEffectPhi(node, block, &block_effects);
350         }
351       } else if (node->opcode() == IrOpcode::kPhi) {
352         // Just skip phis.
353       } else if (node->opcode() == IrOpcode::kTerminate) {
354         DCHECK(terminate == nullptr);
355         terminate = node;
356       } else {
357         break;
358       }
359     }
360 
361     if (effect == nullptr) {
362       // There was no effect phi.
363       DCHECK(!HasIncomingBackEdges(block));
364       if (block == schedule()->start()) {
365         // Start block => effect is start.
366         DCHECK_EQ(graph()->start(), control);
367         effect = graph()->start();
368       } else if (control->opcode() == IrOpcode::kEnd) {
369         // End block is just a dummy, no effect needed.
370         DCHECK_EQ(BasicBlock::kNone, block->control());
371         DCHECK_EQ(1u, block->size());
372         effect = nullptr;
373       } else {
374         // If all the predecessors have the same effect, we can use it as our
375         // current effect.
376         effect =
377             block_effects.For(block->PredecessorAt(0), block).current_effect;
378         for (size_t i = 1; i < block->PredecessorCount(); ++i) {
379           if (block_effects.For(block->PredecessorAt(i), block)
380                   .current_effect != effect) {
381             effect = nullptr;
382             break;
383           }
384         }
385         if (effect == nullptr) {
386           DCHECK_NE(IrOpcode::kIfException, control->opcode());
387           // The input blocks do not have the same effect. We have
388           // to create an effect phi node.
389           inputs_buffer.clear();
390           inputs_buffer.resize(block->PredecessorCount(), jsgraph()->Dead());
391           inputs_buffer.push_back(control);
392           effect = graph()->NewNode(
393               common()->EffectPhi(static_cast<int>(block->PredecessorCount())),
394               static_cast<int>(inputs_buffer.size()), &(inputs_buffer.front()));
395           // For loops, we update the effect phi node later to break cycles.
396           if (control->opcode() == IrOpcode::kLoop) {
397             pending_effect_phis.push_back(PendingEffectPhi(effect, block));
398           } else {
399             UpdateEffectPhi(effect, block, &block_effects);
400           }
401         } else if (control->opcode() == IrOpcode::kIfException) {
402           // The IfException is connected into the effect chain, so we need
403           // to update the effect here.
404           NodeProperties::ReplaceEffectInput(control, effect);
405           effect = control;
406         }
407       }
408     }
409 
410     // Fixup the Terminate node.
411     if (terminate != nullptr) {
412       NodeProperties::ReplaceEffectInput(terminate, effect);
413     }
414 
415     // The frame state at block entry is determined by the frame states leaving
416     // all predecessors. In case there is no frame state dominating this block,
417     // we can rely on a checkpoint being present before the next deoptimization.
418     // TODO(mstarzinger): Eventually we will need to go hunt for a frame state
419     // once deoptimizing nodes roam freely through the schedule.
420     Node* frame_state = nullptr;
421     if (block != schedule()->start()) {
422       // If all the predecessors have the same effect, we can use it
423       // as our current effect.
424       frame_state =
425           block_effects.For(block->PredecessorAt(0), block).current_frame_state;
426       for (size_t i = 1; i < block->PredecessorCount(); i++) {
427         if (block_effects.For(block->PredecessorAt(i), block)
428                 .current_frame_state != frame_state) {
429           frame_state = nullptr;
430           break;
431         }
432       }
433     }
434 
435     // Process the ordinary instructions.
436     for (; instr < block->NodeCount(); instr++) {
437       Node* node = block->NodeAt(instr);
438       ProcessNode(node, &frame_state, &effect, &control);
439     }
440 
441     switch (block->control()) {
442       case BasicBlock::kGoto:
443       case BasicBlock::kNone:
444         break;
445 
446       case BasicBlock::kCall:
447       case BasicBlock::kTailCall:
448       case BasicBlock::kSwitch:
449       case BasicBlock::kReturn:
450       case BasicBlock::kDeoptimize:
451       case BasicBlock::kThrow:
452         ProcessNode(block->control_input(), &frame_state, &effect, &control);
453         break;
454 
455       case BasicBlock::kBranch:
456         ProcessNode(block->control_input(), &frame_state, &effect, &control);
457         TryCloneBranch(block->control_input(), block, graph(), common(),
458                        &block_effects, source_positions_);
459         break;
460     }
461 
462     // Store the effect, control and frame state for later use.
463     for (BasicBlock* successor : block->successors()) {
464       BlockEffectControlData* data = &block_effects.For(block, successor);
465       if (data->current_effect == nullptr) {
466         data->current_effect = effect;
467       }
468       if (data->current_control == nullptr) {
469         data->current_control = control;
470       }
471       data->current_frame_state = frame_state;
472     }
473   }
474 
475   // Update the incoming edges of the effect phis that could not be processed
476   // during the first pass (because they could have incoming back edges).
477   for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) {
478     UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
479                     &block_effects);
480   }
481   for (BasicBlock* pending_block_control : pending_block_controls) {
482     UpdateBlockControl(pending_block_control, &block_effects);
483   }
484 }
485 
486 namespace {
487 
TryScheduleCallIfSuccess(Node * node,Node ** control)488 void TryScheduleCallIfSuccess(Node* node, Node** control) {
489   // Schedule the call's IfSuccess node if there is no exception use.
490   if (!NodeProperties::IsExceptionalCall(node)) {
491     for (Edge edge : node->use_edges()) {
492       if (NodeProperties::IsControlEdge(edge) &&
493           edge.from()->opcode() == IrOpcode::kIfSuccess) {
494         *control = edge.from();
495       }
496     }
497   }
498 }
499 
500 }  // namespace
501 
ProcessNode(Node * node,Node ** frame_state,Node ** effect,Node ** control)502 void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state,
503                                           Node** effect, Node** control) {
504   SourcePositionTable::Scope scope(source_positions_,
505                                    source_positions_->GetSourcePosition(node));
506 
507   // If the node needs to be wired into the effect/control chain, do this
508   // here. Pass current frame state for lowering to eager deoptimization.
509   if (TryWireInStateEffect(node, *frame_state, effect, control)) {
510     return;
511   }
512 
513   // If the node has a visible effect, then there must be a checkpoint in the
514   // effect chain before we are allowed to place another eager deoptimization
515   // point. We zap the frame state to ensure this invariant is maintained.
516   if (region_observability_ == RegionObservability::kObservable &&
517       !node->op()->HasProperty(Operator::kNoWrite)) {
518     *frame_state = nullptr;
519   }
520 
521   // Remove the end markers of 'atomic' allocation region because the
522   // region should be wired-in now.
523   if (node->opcode() == IrOpcode::kFinishRegion) {
524     // Reset the current region observability.
525     region_observability_ = RegionObservability::kObservable;
526     // Update the value uses to the value input of the finish node and
527     // the effect uses to the effect input.
528     return RemoveRegionNode(node);
529   }
530   if (node->opcode() == IrOpcode::kBeginRegion) {
531     // Determine the observability for this region and use that for all
532     // nodes inside the region (i.e. ignore the absence of kNoWrite on
533     // StoreField and other operators).
534     DCHECK_NE(RegionObservability::kNotObservable, region_observability_);
535     region_observability_ = RegionObservabilityOf(node->op());
536     // Update the value uses to the value input of the finish node and
537     // the effect uses to the effect input.
538     return RemoveRegionNode(node);
539   }
540 
541   // Special treatment for checkpoint nodes.
542   if (node->opcode() == IrOpcode::kCheckpoint) {
543     // Unlink the check point; effect uses will be updated to the incoming
544     // effect that is passed. The frame state is preserved for lowering.
545     DCHECK_EQ(RegionObservability::kObservable, region_observability_);
546     *frame_state = NodeProperties::GetFrameStateInput(node);
547     return;
548   }
549 
550   if (node->opcode() == IrOpcode::kIfSuccess) {
551     // We always schedule IfSuccess with its call, so skip it here.
552     DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode());
553     // The IfSuccess node should not belong to an exceptional call node
554     // because such IfSuccess nodes should only start a basic block (and
555     // basic block start nodes are not handled in the ProcessNode method).
556     DCHECK(!NodeProperties::IsExceptionalCall(node->InputAt(0)));
557     return;
558   }
559 
560   // If the node takes an effect, replace with the current one.
561   if (node->op()->EffectInputCount() > 0) {
562     DCHECK_EQ(1, node->op()->EffectInputCount());
563     Node* input_effect = NodeProperties::GetEffectInput(node);
564 
565     if (input_effect != *effect) {
566       NodeProperties::ReplaceEffectInput(node, *effect);
567     }
568 
569     // If the node produces an effect, update our current effect. (However,
570     // ignore new effect chains started with ValueEffect.)
571     if (node->op()->EffectOutputCount() > 0) {
572       DCHECK_EQ(1, node->op()->EffectOutputCount());
573       *effect = node;
574     }
575   } else {
576     // New effect chain is only started with a Start or ValueEffect node.
577     DCHECK(node->op()->EffectOutputCount() == 0 ||
578            node->opcode() == IrOpcode::kStart);
579   }
580 
581   // Rewire control inputs.
582   for (int i = 0; i < node->op()->ControlInputCount(); i++) {
583     NodeProperties::ReplaceControlInput(node, *control, i);
584   }
585   // Update the current control and wire IfSuccess right after calls.
586   if (node->op()->ControlOutputCount() > 0) {
587     *control = node;
588     if (node->opcode() == IrOpcode::kCall) {
589       // Schedule the call's IfSuccess node (if there is no exception use).
590       TryScheduleCallIfSuccess(node, control);
591     }
592   }
593 }
594 
TryWireInStateEffect(Node * node,Node * frame_state,Node ** effect,Node ** control)595 bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
596                                                    Node* frame_state,
597                                                    Node** effect,
598                                                    Node** control) {
599   ValueEffectControl state(nullptr, nullptr, nullptr);
600   switch (node->opcode()) {
601     case IrOpcode::kChangeBitToTagged:
602       state = LowerChangeBitToTagged(node, *effect, *control);
603       break;
604     case IrOpcode::kChangeInt31ToTaggedSigned:
605       state = LowerChangeInt31ToTaggedSigned(node, *effect, *control);
606       break;
607     case IrOpcode::kChangeInt32ToTagged:
608       state = LowerChangeInt32ToTagged(node, *effect, *control);
609       break;
610     case IrOpcode::kChangeUint32ToTagged:
611       state = LowerChangeUint32ToTagged(node, *effect, *control);
612       break;
613     case IrOpcode::kChangeFloat64ToTagged:
614       state = LowerChangeFloat64ToTagged(node, *effect, *control);
615       break;
616     case IrOpcode::kChangeFloat64ToTaggedPointer:
617       state = LowerChangeFloat64ToTaggedPointer(node, *effect, *control);
618       break;
619     case IrOpcode::kChangeTaggedSignedToInt32:
620       state = LowerChangeTaggedSignedToInt32(node, *effect, *control);
621       break;
622     case IrOpcode::kChangeTaggedToBit:
623       state = LowerChangeTaggedToBit(node, *effect, *control);
624       break;
625     case IrOpcode::kChangeTaggedToInt32:
626       state = LowerChangeTaggedToInt32(node, *effect, *control);
627       break;
628     case IrOpcode::kChangeTaggedToUint32:
629       state = LowerChangeTaggedToUint32(node, *effect, *control);
630       break;
631     case IrOpcode::kChangeTaggedToFloat64:
632       state = LowerChangeTaggedToFloat64(node, *effect, *control);
633       break;
634     case IrOpcode::kTruncateTaggedToBit:
635       state = LowerTruncateTaggedToBit(node, *effect, *control);
636       break;
637     case IrOpcode::kTruncateTaggedToFloat64:
638       state = LowerTruncateTaggedToFloat64(node, *effect, *control);
639       break;
640     case IrOpcode::kCheckBounds:
641       state = LowerCheckBounds(node, frame_state, *effect, *control);
642       break;
643     case IrOpcode::kCheckMaps:
644       state = LowerCheckMaps(node, frame_state, *effect, *control);
645       break;
646     case IrOpcode::kCheckNumber:
647       state = LowerCheckNumber(node, frame_state, *effect, *control);
648       break;
649     case IrOpcode::kCheckString:
650       state = LowerCheckString(node, frame_state, *effect, *control);
651       break;
652     case IrOpcode::kCheckIf:
653       state = LowerCheckIf(node, frame_state, *effect, *control);
654       break;
655     case IrOpcode::kCheckedInt32Add:
656       state = LowerCheckedInt32Add(node, frame_state, *effect, *control);
657       break;
658     case IrOpcode::kCheckedInt32Sub:
659       state = LowerCheckedInt32Sub(node, frame_state, *effect, *control);
660       break;
661     case IrOpcode::kCheckedInt32Div:
662       state = LowerCheckedInt32Div(node, frame_state, *effect, *control);
663       break;
664     case IrOpcode::kCheckedInt32Mod:
665       state = LowerCheckedInt32Mod(node, frame_state, *effect, *control);
666       break;
667     case IrOpcode::kCheckedUint32Div:
668       state = LowerCheckedUint32Div(node, frame_state, *effect, *control);
669       break;
670     case IrOpcode::kCheckedUint32Mod:
671       state = LowerCheckedUint32Mod(node, frame_state, *effect, *control);
672       break;
673     case IrOpcode::kCheckedInt32Mul:
674       state = LowerCheckedInt32Mul(node, frame_state, *effect, *control);
675       break;
676     case IrOpcode::kCheckedInt32ToTaggedSigned:
677       state =
678           LowerCheckedInt32ToTaggedSigned(node, frame_state, *effect, *control);
679       break;
680     case IrOpcode::kCheckedUint32ToInt32:
681       state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control);
682       break;
683     case IrOpcode::kCheckedUint32ToTaggedSigned:
684       state = LowerCheckedUint32ToTaggedSigned(node, frame_state, *effect,
685                                                *control);
686       break;
687     case IrOpcode::kCheckedFloat64ToInt32:
688       state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control);
689       break;
690     case IrOpcode::kCheckedTaggedSignedToInt32:
691       state =
692           LowerCheckedTaggedSignedToInt32(node, frame_state, *effect, *control);
693       break;
694     case IrOpcode::kCheckedTaggedToInt32:
695       state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control);
696       break;
697     case IrOpcode::kCheckedTaggedToFloat64:
698       state = LowerCheckedTaggedToFloat64(node, frame_state, *effect, *control);
699       break;
700     case IrOpcode::kCheckedTaggedToTaggedSigned:
701       state = LowerCheckedTaggedToTaggedSigned(node, frame_state, *effect,
702                                                *control);
703       break;
704     case IrOpcode::kCheckedTaggedToTaggedPointer:
705       state = LowerCheckedTaggedToTaggedPointer(node, frame_state, *effect,
706                                                 *control);
707       break;
708     case IrOpcode::kTruncateTaggedToWord32:
709       state = LowerTruncateTaggedToWord32(node, *effect, *control);
710       break;
711     case IrOpcode::kCheckedTruncateTaggedToWord32:
712       state = LowerCheckedTruncateTaggedToWord32(node, frame_state, *effect,
713                                                  *control);
714       break;
715     case IrOpcode::kObjectIsCallable:
716       state = LowerObjectIsCallable(node, *effect, *control);
717       break;
718     case IrOpcode::kObjectIsNumber:
719       state = LowerObjectIsNumber(node, *effect, *control);
720       break;
721     case IrOpcode::kObjectIsReceiver:
722       state = LowerObjectIsReceiver(node, *effect, *control);
723       break;
724     case IrOpcode::kObjectIsSmi:
725       state = LowerObjectIsSmi(node, *effect, *control);
726       break;
727     case IrOpcode::kObjectIsString:
728       state = LowerObjectIsString(node, *effect, *control);
729       break;
730     case IrOpcode::kObjectIsUndetectable:
731       state = LowerObjectIsUndetectable(node, *effect, *control);
732       break;
733     case IrOpcode::kArrayBufferWasNeutered:
734       state = LowerArrayBufferWasNeutered(node, *effect, *control);
735       break;
736     case IrOpcode::kStringFromCharCode:
737       state = LowerStringFromCharCode(node, *effect, *control);
738       break;
739     case IrOpcode::kStringFromCodePoint:
740       state = LowerStringFromCodePoint(node, *effect, *control);
741       break;
742     case IrOpcode::kStringCharCodeAt:
743       state = LowerStringCharCodeAt(node, *effect, *control);
744       break;
745     case IrOpcode::kStringEqual:
746       state = LowerStringEqual(node, *effect, *control);
747       break;
748     case IrOpcode::kStringLessThan:
749       state = LowerStringLessThan(node, *effect, *control);
750       break;
751     case IrOpcode::kStringLessThanOrEqual:
752       state = LowerStringLessThanOrEqual(node, *effect, *control);
753       break;
754     case IrOpcode::kCheckFloat64Hole:
755       state = LowerCheckFloat64Hole(node, frame_state, *effect, *control);
756       break;
757     case IrOpcode::kCheckTaggedHole:
758       state = LowerCheckTaggedHole(node, frame_state, *effect, *control);
759       break;
760     case IrOpcode::kConvertTaggedHoleToUndefined:
761       state = LowerConvertTaggedHoleToUndefined(node, *effect, *control);
762       break;
763     case IrOpcode::kPlainPrimitiveToNumber:
764       state = LowerPlainPrimitiveToNumber(node, *effect, *control);
765       break;
766     case IrOpcode::kPlainPrimitiveToWord32:
767       state = LowerPlainPrimitiveToWord32(node, *effect, *control);
768       break;
769     case IrOpcode::kPlainPrimitiveToFloat64:
770       state = LowerPlainPrimitiveToFloat64(node, *effect, *control);
771       break;
772     case IrOpcode::kEnsureWritableFastElements:
773       state = LowerEnsureWritableFastElements(node, *effect, *control);
774       break;
775     case IrOpcode::kMaybeGrowFastElements:
776       state = LowerMaybeGrowFastElements(node, frame_state, *effect, *control);
777       break;
778     case IrOpcode::kTransitionElementsKind:
779       state = LowerTransitionElementsKind(node, *effect, *control);
780       break;
781     case IrOpcode::kLoadTypedElement:
782       state = LowerLoadTypedElement(node, *effect, *control);
783       break;
784     case IrOpcode::kStoreTypedElement:
785       state = LowerStoreTypedElement(node, *effect, *control);
786       break;
787     case IrOpcode::kFloat64RoundUp:
788       state = LowerFloat64RoundUp(node, *effect, *control);
789       break;
790     case IrOpcode::kFloat64RoundDown:
791       state = LowerFloat64RoundDown(node, *effect, *control);
792       break;
793     case IrOpcode::kFloat64RoundTruncate:
794       state = LowerFloat64RoundTruncate(node, *effect, *control);
795       break;
796     case IrOpcode::kFloat64RoundTiesEven:
797       state = LowerFloat64RoundTiesEven(node, *effect, *control);
798       break;
799     default:
800       return false;
801   }
802   NodeProperties::ReplaceUses(node, state.value, state.effect, state.control);
803   *effect = state.effect;
804   *control = state.control;
805   return true;
806 }
807 
808 EffectControlLinearizer::ValueEffectControl
LowerChangeFloat64ToTagged(Node * node,Node * effect,Node * control)809 EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect,
810                                                     Node* control) {
811   Node* value = node->InputAt(0);
812   return AllocateHeapNumberWithValue(value, effect, control);
813 }
814 
815 EffectControlLinearizer::ValueEffectControl
LowerChangeFloat64ToTaggedPointer(Node * node,Node * effect,Node * control)816 EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node,
817                                                            Node* effect,
818                                                            Node* control) {
819   Node* value = node->InputAt(0);
820   return AllocateHeapNumberWithValue(value, effect, control);
821 }
822 
823 EffectControlLinearizer::ValueEffectControl
LowerChangeBitToTagged(Node * node,Node * effect,Node * control)824 EffectControlLinearizer::LowerChangeBitToTagged(Node* node, Node* effect,
825                                                 Node* control) {
826   Node* value = node->InputAt(0);
827 
828   Node* branch = graph()->NewNode(common()->Branch(), value, control);
829 
830   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
831   Node* vtrue = jsgraph()->TrueConstant();
832 
833   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
834   Node* vfalse = jsgraph()->FalseConstant();
835 
836   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
837   value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
838                            vtrue, vfalse, control);
839 
840   return ValueEffectControl(value, effect, control);
841 }
842 
843 EffectControlLinearizer::ValueEffectControl
LowerChangeInt31ToTaggedSigned(Node * node,Node * effect,Node * control)844 EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node,
845                                                         Node* effect,
846                                                         Node* control) {
847   Node* value = node->InputAt(0);
848   value = ChangeInt32ToSmi(value);
849   return ValueEffectControl(value, effect, control);
850 }
851 
852 EffectControlLinearizer::ValueEffectControl
LowerChangeInt32ToTagged(Node * node,Node * effect,Node * control)853 EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node, Node* effect,
854                                                   Node* control) {
855   Node* value = node->InputAt(0);
856 
857   if (machine()->Is64()) {
858     return ValueEffectControl(ChangeInt32ToSmi(value), effect, control);
859   }
860 
861   Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value,
862                                control);
863 
864   Node* ovf = graph()->NewNode(common()->Projection(1), add, control);
865   Node* branch =
866       graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control);
867 
868   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
869   ValueEffectControl alloc =
870       AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), effect, if_true);
871 
872   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
873   Node* vfalse = graph()->NewNode(common()->Projection(0), add, if_false);
874 
875   Node* merge = graph()->NewNode(common()->Merge(2), alloc.control, if_false);
876   Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
877                                alloc.value, vfalse, merge);
878   Node* ephi =
879       graph()->NewNode(common()->EffectPhi(2), alloc.effect, effect, merge);
880 
881   return ValueEffectControl(phi, ephi, merge);
882 }
883 
884 EffectControlLinearizer::ValueEffectControl
LowerChangeUint32ToTagged(Node * node,Node * effect,Node * control)885 EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node, Node* effect,
886                                                    Node* control) {
887   Node* value = node->InputAt(0);
888 
889   Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value,
890                                  SmiMaxValueConstant());
891   Node* branch =
892       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
893 
894   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
895   Node* vtrue = ChangeUint32ToSmi(value);
896 
897   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
898   ValueEffectControl alloc = AllocateHeapNumberWithValue(
899       ChangeUint32ToFloat64(value), effect, if_false);
900 
901   Node* merge = graph()->NewNode(common()->Merge(2), if_true, alloc.control);
902   Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
903                                vtrue, alloc.value, merge);
904   Node* ephi =
905       graph()->NewNode(common()->EffectPhi(2), effect, alloc.effect, merge);
906 
907   return ValueEffectControl(phi, ephi, merge);
908 }
909 
910 EffectControlLinearizer::ValueEffectControl
LowerChangeTaggedSignedToInt32(Node * node,Node * effect,Node * control)911 EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node,
912                                                         Node* effect,
913                                                         Node* control) {
914   Node* value = node->InputAt(0);
915   value = ChangeSmiToInt32(value);
916   return ValueEffectControl(value, effect, control);
917 }
918 
919 EffectControlLinearizer::ValueEffectControl
LowerChangeTaggedToBit(Node * node,Node * effect,Node * control)920 EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect,
921                                                 Node* control) {
922   Node* value = node->InputAt(0);
923   value = graph()->NewNode(machine()->WordEqual(), value,
924                            jsgraph()->TrueConstant());
925   return ValueEffectControl(value, effect, control);
926 }
927 
928 EffectControlLinearizer::ValueEffectControl
LowerTruncateTaggedToBit(Node * node,Node * effect,Node * control)929 EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node, Node* effect,
930                                                   Node* control) {
931   Node* value = node->InputAt(0);
932   Node* zero = jsgraph()->Int32Constant(0);
933   Node* fzero = jsgraph()->Float64Constant(0.0);
934 
935   // Collect effect/control/value triples.
936   int count = 0;
937   Node* values[6];
938   Node* effects[6];
939   Node* controls[5];
940 
941   // Check if {value} is a Smi.
942   Node* check_smi = ObjectIsSmi(value);
943   Node* branch_smi = graph()->NewNode(common()->Branch(BranchHint::kFalse),
944                                       check_smi, control);
945 
946   // If {value} is a Smi, then we only need to check that it's not zero.
947   Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_smi);
948   Node* esmi = effect;
949   {
950     controls[count] = if_smi;
951     effects[count] = esmi;
952     values[count] =
953         graph()->NewNode(machine()->Word32Equal(),
954                          graph()->NewNode(machine()->WordEqual(), value,
955                                           jsgraph()->IntPtrConstant(0)),
956                          zero);
957     count++;
958   }
959   control = graph()->NewNode(common()->IfFalse(), branch_smi);
960 
961   // Load the map instance type of {value}.
962   Node* value_map = effect = graph()->NewNode(
963       simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
964   Node* value_instance_type = effect = graph()->NewNode(
965       simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
966       effect, control);
967 
968   // Check if {value} is an Oddball.
969   Node* check_oddball =
970       graph()->NewNode(machine()->Word32Equal(), value_instance_type,
971                        jsgraph()->Int32Constant(ODDBALL_TYPE));
972   Node* branch_oddball = graph()->NewNode(common()->Branch(BranchHint::kTrue),
973                                           check_oddball, control);
974 
975   // The only Oddball {value} that is trueish is true itself.
976   Node* if_oddball = graph()->NewNode(common()->IfTrue(), branch_oddball);
977   Node* eoddball = effect;
978   {
979     controls[count] = if_oddball;
980     effects[count] = eoddball;
981     values[count] = graph()->NewNode(machine()->WordEqual(), value,
982                                      jsgraph()->TrueConstant());
983     count++;
984   }
985   control = graph()->NewNode(common()->IfFalse(), branch_oddball);
986 
987   // Check if {value} is a String.
988   Node* check_string =
989       graph()->NewNode(machine()->Int32LessThan(), value_instance_type,
990                        jsgraph()->Int32Constant(FIRST_NONSTRING_TYPE));
991   Node* branch_string =
992       graph()->NewNode(common()->Branch(), check_string, control);
993 
994   // For String {value}, we need to check that the length is not zero.
995   Node* if_string = graph()->NewNode(common()->IfTrue(), branch_string);
996   Node* estring = effect;
997   {
998     // Load the {value} length.
999     Node* value_length = estring = graph()->NewNode(
1000         simplified()->LoadField(AccessBuilder::ForStringLength()), value,
1001         estring, if_string);
1002 
1003     controls[count] = if_string;
1004     effects[count] = estring;
1005     values[count] =
1006         graph()->NewNode(machine()->Word32Equal(),
1007                          graph()->NewNode(machine()->WordEqual(), value_length,
1008                                           jsgraph()->IntPtrConstant(0)),
1009                          zero);
1010     count++;
1011   }
1012   control = graph()->NewNode(common()->IfFalse(), branch_string);
1013 
1014   // Check if {value} is a HeapNumber.
1015   Node* check_heapnumber =
1016       graph()->NewNode(machine()->Word32Equal(), value_instance_type,
1017                        jsgraph()->Int32Constant(HEAP_NUMBER_TYPE));
1018   Node* branch_heapnumber =
1019       graph()->NewNode(common()->Branch(), check_heapnumber, control);
1020 
1021   // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or NaN.
1022   Node* if_heapnumber = graph()->NewNode(common()->IfTrue(), branch_heapnumber);
1023   Node* eheapnumber = effect;
1024   {
1025     // Load the raw value of {value}.
1026     Node* value_value = eheapnumber = graph()->NewNode(
1027         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1028         eheapnumber, if_heapnumber);
1029 
1030     // Check if {value} is not one of 0, -0, or NaN.
1031     controls[count] = if_heapnumber;
1032     effects[count] = eheapnumber;
1033     values[count] = graph()->NewNode(
1034         machine()->Float64LessThan(), fzero,
1035         graph()->NewNode(machine()->Float64Abs(), value_value));
1036     count++;
1037   }
1038   control = graph()->NewNode(common()->IfFalse(), branch_heapnumber);
1039 
1040   // The {value} is either a JSReceiver, a Symbol or some Simd128Value. In
1041   // those cases we can just the undetectable bit on the map, which will only
1042   // be set for certain JSReceivers, i.e. document.all.
1043   {
1044     // Load the {value} map bit field.
1045     Node* value_map_bitfield = effect = graph()->NewNode(
1046         simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
1047         effect, control);
1048 
1049     controls[count] = control;
1050     effects[count] = effect;
1051     values[count] = graph()->NewNode(
1052         machine()->Word32Equal(),
1053         graph()->NewNode(machine()->Word32And(), value_map_bitfield,
1054                          jsgraph()->Int32Constant(1 << Map::kIsUndetectable)),
1055         zero);
1056     count++;
1057   }
1058 
1059   // Merge the different controls.
1060   control = graph()->NewNode(common()->Merge(count), count, controls);
1061   effects[count] = control;
1062   effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects);
1063   values[count] = control;
1064   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, count),
1065                            count + 1, values);
1066 
1067   return ValueEffectControl(value, effect, control);
1068 }
1069 
1070 EffectControlLinearizer::ValueEffectControl
LowerChangeTaggedToInt32(Node * node,Node * effect,Node * control)1071 EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect,
1072                                                   Node* control) {
1073   Node* value = node->InputAt(0);
1074 
1075   Node* check = ObjectIsSmi(value);
1076   Node* branch =
1077       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1078 
1079   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1080   Node* etrue = effect;
1081   Node* vtrue = ChangeSmiToInt32(value);
1082 
1083   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1084   Node* efalse = effect;
1085   Node* vfalse;
1086   {
1087     STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1088     vfalse = efalse = graph()->NewNode(
1089         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1090         efalse, if_false);
1091     vfalse = graph()->NewNode(machine()->ChangeFloat64ToInt32(), vfalse);
1092   }
1093 
1094   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1095   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1096   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1097                            vtrue, vfalse, control);
1098 
1099   return ValueEffectControl(value, effect, control);
1100 }
1101 
1102 EffectControlLinearizer::ValueEffectControl
LowerChangeTaggedToUint32(Node * node,Node * effect,Node * control)1103 EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node, Node* effect,
1104                                                    Node* control) {
1105   Node* value = node->InputAt(0);
1106 
1107   Node* check = ObjectIsSmi(value);
1108   Node* branch =
1109       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1110 
1111   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1112   Node* etrue = effect;
1113   Node* vtrue = ChangeSmiToInt32(value);
1114 
1115   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1116   Node* efalse = effect;
1117   Node* vfalse;
1118   {
1119     STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1120     vfalse = efalse = graph()->NewNode(
1121         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1122         efalse, if_false);
1123     vfalse = graph()->NewNode(machine()->ChangeFloat64ToUint32(), vfalse);
1124   }
1125 
1126   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1127   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1128   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1129                            vtrue, vfalse, control);
1130 
1131   return ValueEffectControl(value, effect, control);
1132 }
1133 
1134 EffectControlLinearizer::ValueEffectControl
LowerChangeTaggedToFloat64(Node * node,Node * effect,Node * control)1135 EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node, Node* effect,
1136                                                     Node* control) {
1137   return LowerTruncateTaggedToFloat64(node, effect, control);
1138 }
1139 
1140 EffectControlLinearizer::ValueEffectControl
LowerTruncateTaggedToFloat64(Node * node,Node * effect,Node * control)1141 EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node, Node* effect,
1142                                                       Node* control) {
1143   Node* value = node->InputAt(0);
1144 
1145   Node* check = ObjectIsSmi(value);
1146   Node* branch =
1147       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1148 
1149   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1150   Node* etrue = effect;
1151   Node* vtrue;
1152   {
1153     vtrue = ChangeSmiToInt32(value);
1154     vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue);
1155   }
1156 
1157   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1158   Node* efalse = effect;
1159   Node* vfalse;
1160   {
1161     STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1162     vfalse = efalse = graph()->NewNode(
1163         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1164         efalse, if_false);
1165   }
1166 
1167   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1168   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1169   value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1170                            vtrue, vfalse, control);
1171 
1172   return ValueEffectControl(value, effect, control);
1173 }
1174 
1175 EffectControlLinearizer::ValueEffectControl
LowerCheckBounds(Node * node,Node * frame_state,Node * effect,Node * control)1176 EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state,
1177                                           Node* effect, Node* control) {
1178   Node* index = node->InputAt(0);
1179   Node* limit = node->InputAt(1);
1180 
1181   Node* check = graph()->NewNode(machine()->Uint32LessThan(), index, limit);
1182   control = effect = graph()->NewNode(
1183       common()->DeoptimizeUnless(DeoptimizeReason::kOutOfBounds), check,
1184       frame_state, effect, control);
1185 
1186   return ValueEffectControl(index, effect, control);
1187 }
1188 
1189 EffectControlLinearizer::ValueEffectControl
LowerCheckMaps(Node * node,Node * frame_state,Node * effect,Node * control)1190 EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state,
1191                                         Node* effect, Node* control) {
1192   Node* value = node->InputAt(0);
1193 
1194   // Load the current map of the {value}.
1195   Node* value_map = effect = graph()->NewNode(
1196       simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
1197 
1198   int const map_count = node->op()->ValueInputCount() - 1;
1199   Node** controls = temp_zone()->NewArray<Node*>(map_count);
1200   Node** effects = temp_zone()->NewArray<Node*>(map_count + 1);
1201 
1202   for (int i = 0; i < map_count; ++i) {
1203     Node* map = node->InputAt(1 + i);
1204 
1205     Node* check = graph()->NewNode(machine()->WordEqual(), value_map, map);
1206     if (i == map_count - 1) {
1207       controls[i] = effects[i] = graph()->NewNode(
1208           common()->DeoptimizeUnless(DeoptimizeReason::kWrongMap), check,
1209           frame_state, effect, control);
1210     } else {
1211       control = graph()->NewNode(common()->Branch(), check, control);
1212       controls[i] = graph()->NewNode(common()->IfTrue(), control);
1213       control = graph()->NewNode(common()->IfFalse(), control);
1214       effects[i] = effect;
1215     }
1216   }
1217 
1218   control = graph()->NewNode(common()->Merge(map_count), map_count, controls);
1219   effects[map_count] = control;
1220   effect =
1221       graph()->NewNode(common()->EffectPhi(map_count), map_count + 1, effects);
1222 
1223   return ValueEffectControl(value, effect, control);
1224 }
1225 
1226 EffectControlLinearizer::ValueEffectControl
LowerCheckNumber(Node * node,Node * frame_state,Node * effect,Node * control)1227 EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state,
1228                                           Node* effect, Node* control) {
1229   Node* value = node->InputAt(0);
1230 
1231   Node* check0 = ObjectIsSmi(value);
1232   Node* branch0 =
1233       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
1234 
1235   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1236   Node* etrue0 = effect;
1237 
1238   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1239   Node* efalse0 = effect;
1240   {
1241     Node* value_map = efalse0 =
1242         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
1243                          value, efalse0, if_false0);
1244     Node* check1 = graph()->NewNode(machine()->WordEqual(), value_map,
1245                                     jsgraph()->HeapNumberMapConstant());
1246     if_false0 = efalse0 = graph()->NewNode(
1247         common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber), check1,
1248         frame_state, efalse0, if_false0);
1249   }
1250 
1251   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1252   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1253 
1254   return ValueEffectControl(value, effect, control);
1255 }
1256 
1257 EffectControlLinearizer::ValueEffectControl
LowerCheckString(Node * node,Node * frame_state,Node * effect,Node * control)1258 EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state,
1259                                           Node* effect, Node* control) {
1260   Node* value = node->InputAt(0);
1261 
1262   Node* check0 = ObjectIsSmi(value);
1263   control = effect =
1264       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check0,
1265                        frame_state, effect, control);
1266 
1267   Node* value_map = effect = graph()->NewNode(
1268       simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
1269   Node* value_instance_type = effect = graph()->NewNode(
1270       simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
1271       effect, control);
1272 
1273   Node* check1 =
1274       graph()->NewNode(machine()->Uint32LessThan(), value_instance_type,
1275                        jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE));
1276   control = effect = graph()->NewNode(
1277       common()->DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType), check1,
1278       frame_state, effect, control);
1279 
1280   return ValueEffectControl(value, effect, control);
1281 }
1282 
1283 EffectControlLinearizer::ValueEffectControl
LowerCheckIf(Node * node,Node * frame_state,Node * effect,Node * control)1284 EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state,
1285                                       Node* effect, Node* control) {
1286   Node* value = node->InputAt(0);
1287 
1288   control = effect =
1289       graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNoReason),
1290                        value, frame_state, effect, control);
1291 
1292   return ValueEffectControl(value, effect, control);
1293 }
1294 
1295 EffectControlLinearizer::ValueEffectControl
LowerCheckedInt32Add(Node * node,Node * frame_state,Node * effect,Node * control)1296 EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* frame_state,
1297                                               Node* effect, Node* control) {
1298   Node* lhs = node->InputAt(0);
1299   Node* rhs = node->InputAt(1);
1300 
1301   Node* value =
1302       graph()->NewNode(machine()->Int32AddWithOverflow(), lhs, rhs, control);
1303 
1304   Node* check = graph()->NewNode(common()->Projection(1), value, control);
1305   control = effect =
1306       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
1307                        check, frame_state, effect, control);
1308 
1309   value = graph()->NewNode(common()->Projection(0), value, control);
1310 
1311   return ValueEffectControl(value, effect, control);
1312 }
1313 
1314 EffectControlLinearizer::ValueEffectControl
LowerCheckedInt32Sub(Node * node,Node * frame_state,Node * effect,Node * control)1315 EffectControlLinearizer::LowerCheckedInt32Sub(Node* node, Node* frame_state,
1316                                               Node* effect, Node* control) {
1317   Node* lhs = node->InputAt(0);
1318   Node* rhs = node->InputAt(1);
1319 
1320   Node* value =
1321       graph()->NewNode(machine()->Int32SubWithOverflow(), lhs, rhs, control);
1322 
1323   Node* check = graph()->NewNode(common()->Projection(1), value, control);
1324   control = effect =
1325       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
1326                        check, frame_state, effect, control);
1327 
1328   value = graph()->NewNode(common()->Projection(0), value, control);
1329 
1330   return ValueEffectControl(value, effect, control);
1331 }
1332 
1333 EffectControlLinearizer::ValueEffectControl
LowerCheckedInt32Div(Node * node,Node * frame_state,Node * effect,Node * control)1334 EffectControlLinearizer::LowerCheckedInt32Div(Node* node, Node* frame_state,
1335                                               Node* effect, Node* control) {
1336   Node* zero = jsgraph()->Int32Constant(0);
1337   Node* minusone = jsgraph()->Int32Constant(-1);
1338   Node* minint = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::min());
1339 
1340   Node* lhs = node->InputAt(0);
1341   Node* rhs = node->InputAt(1);
1342 
1343   // Check if {rhs} is positive (and not zero).
1344   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
1345   Node* branch0 =
1346       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
1347 
1348   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1349   Node* etrue0 = effect;
1350   Node* vtrue0;
1351   {
1352     // Fast case, no additional checking required.
1353     vtrue0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0);
1354   }
1355 
1356   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1357   Node* efalse0 = effect;
1358   Node* vfalse0;
1359   {
1360     // Check if {rhs} is zero.
1361     Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
1362     if_false0 = efalse0 = graph()->NewNode(
1363         common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
1364         frame_state, efalse0, if_false0);
1365 
1366     // Check if {lhs} is zero, as that would produce minus zero.
1367     check = graph()->NewNode(machine()->Word32Equal(), lhs, zero);
1368     if_false0 = efalse0 =
1369         graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
1370                          check, frame_state, efalse0, if_false0);
1371 
1372     // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have
1373     // to return -kMinInt, which is not representable.
1374     Node* check1 = graph()->NewNode(machine()->Word32Equal(), lhs, minint);
1375     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1376                                      check1, if_false0);
1377 
1378     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1379     Node* etrue1 = efalse0;
1380     {
1381       // Check if {rhs} is -1.
1382       Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, minusone);
1383       if_true1 = etrue1 =
1384           graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
1385                            check, frame_state, etrue1, if_true1);
1386     }
1387 
1388     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1389     Node* efalse1 = efalse0;
1390 
1391     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1392     efalse0 =
1393         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
1394 
1395     // Perform the actual integer division.
1396     vfalse0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_false0);
1397   }
1398 
1399   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1400   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1401   Node* value =
1402       graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0,
1403                        vfalse0, control);
1404 
1405   // Check if the remainder is non-zero.
1406   Node* check =
1407       graph()->NewNode(machine()->Word32Equal(), lhs,
1408                        graph()->NewNode(machine()->Int32Mul(), rhs, value));
1409   control = effect = graph()->NewNode(
1410       common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check,
1411       frame_state, effect, control);
1412 
1413   return ValueEffectControl(value, effect, control);
1414 }
1415 
1416 EffectControlLinearizer::ValueEffectControl
LowerCheckedInt32Mod(Node * node,Node * frame_state,Node * effect,Node * control)1417 EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state,
1418                                               Node* effect, Node* control) {
1419   Node* zero = jsgraph()->Int32Constant(0);
1420   Node* one = jsgraph()->Int32Constant(1);
1421 
1422   // General case for signed integer modulus, with optimization for (unknown)
1423   // power of 2 right hand side.
1424   //
1425   //   if rhs <= 0 then
1426   //     rhs = -rhs
1427   //     deopt if rhs == 0
1428   //   if lhs < 0 then
1429   //     let res = lhs % rhs in
1430   //     deopt if res == 0
1431   //     res
1432   //   else
1433   //     let msk = rhs - 1 in
1434   //     if rhs & msk == 0 then
1435   //       lhs & msk
1436   //     else
1437   //       lhs % rhs
1438   //
1439   Node* lhs = node->InputAt(0);
1440   Node* rhs = node->InputAt(1);
1441 
1442   // Check if {rhs} is not strictly positive.
1443   Node* check0 = graph()->NewNode(machine()->Int32LessThanOrEqual(), rhs, zero);
1444   Node* branch0 =
1445       graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control);
1446 
1447   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1448   Node* etrue0 = effect;
1449   Node* vtrue0;
1450   {
1451     // Negate {rhs}, might still produce a negative result in case of
1452     // -2^31, but that is handled safely below.
1453     vtrue0 = graph()->NewNode(machine()->Int32Sub(), zero, rhs);
1454 
1455     // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
1456     Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue0, zero);
1457     if_true0 = etrue0 = graph()->NewNode(
1458         common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
1459         frame_state, etrue0, if_true0);
1460   }
1461 
1462   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1463   Node* efalse0 = effect;
1464   Node* vfalse0 = rhs;
1465 
1466   // At this point {rhs} is either greater than zero or -2^31, both are
1467   // fine for the code that follows.
1468   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1469   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1470   rhs = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1471                          vtrue0, vfalse0, control);
1472 
1473   // Check if {lhs} is negative.
1474   Node* check1 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
1475   Node* branch1 =
1476       graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control);
1477 
1478   Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1479   Node* etrue1 = effect;
1480   Node* vtrue1;
1481   {
1482     // Compute the remainder using {lhs % msk}.
1483     vtrue1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
1484 
1485     // Check if we would have to return -0.
1486     Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue1, zero);
1487     if_true1 = etrue1 =
1488         graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
1489                          check, frame_state, etrue1, if_true1);
1490   }
1491 
1492   Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1493   Node* efalse1 = effect;
1494   Node* vfalse1;
1495   {
1496     Node* msk = graph()->NewNode(machine()->Int32Sub(), rhs, one);
1497 
1498     // Check if {rhs} minus one is a valid mask.
1499     Node* check2 = graph()->NewNode(
1500         machine()->Word32Equal(),
1501         graph()->NewNode(machine()->Word32And(), rhs, msk), zero);
1502     Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
1503 
1504     // Compute the remainder using {lhs & msk}.
1505     Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1506     Node* vtrue2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
1507 
1508     // Compute the remainder using the generic {lhs % rhs}.
1509     Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
1510     Node* vfalse2 =
1511         graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false2);
1512 
1513     if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
1514     vfalse1 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1515                                vtrue2, vfalse2, if_false1);
1516   }
1517 
1518   control = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1519   effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control);
1520   Node* value =
1521       graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue1,
1522                        vfalse1, control);
1523 
1524   return ValueEffectControl(value, effect, control);
1525 }
1526 
1527 EffectControlLinearizer::ValueEffectControl
LowerCheckedUint32Div(Node * node,Node * frame_state,Node * effect,Node * control)1528 EffectControlLinearizer::LowerCheckedUint32Div(Node* node, Node* frame_state,
1529                                                Node* effect, Node* control) {
1530   Node* zero = jsgraph()->Int32Constant(0);
1531 
1532   Node* lhs = node->InputAt(0);
1533   Node* rhs = node->InputAt(1);
1534 
1535   // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
1536   Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
1537   control = effect = graph()->NewNode(
1538       common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
1539       frame_state, effect, control);
1540 
1541   // Perform the actual unsigned integer division.
1542   Node* value = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, control);
1543 
1544   // Check if the remainder is non-zero.
1545   check = graph()->NewNode(machine()->Word32Equal(), lhs,
1546                            graph()->NewNode(machine()->Int32Mul(), rhs, value));
1547   control = effect = graph()->NewNode(
1548       common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check,
1549       frame_state, effect, control);
1550 
1551   return ValueEffectControl(value, effect, control);
1552 }
1553 
1554 EffectControlLinearizer::ValueEffectControl
LowerCheckedUint32Mod(Node * node,Node * frame_state,Node * effect,Node * control)1555 EffectControlLinearizer::LowerCheckedUint32Mod(Node* node, Node* frame_state,
1556                                                Node* effect, Node* control) {
1557   Node* zero = jsgraph()->Int32Constant(0);
1558 
1559   Node* lhs = node->InputAt(0);
1560   Node* rhs = node->InputAt(1);
1561 
1562   // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
1563   Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
1564   control = effect = graph()->NewNode(
1565       common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
1566       frame_state, effect, control);
1567 
1568   // Perform the actual unsigned integer modulus.
1569   Node* value = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, control);
1570 
1571   return ValueEffectControl(value, effect, control);
1572 }
1573 
1574 EffectControlLinearizer::ValueEffectControl
LowerCheckedInt32Mul(Node * node,Node * frame_state,Node * effect,Node * control)1575 EffectControlLinearizer::LowerCheckedInt32Mul(Node* node, Node* frame_state,
1576                                               Node* effect, Node* control) {
1577   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
1578   Node* zero = jsgraph()->Int32Constant(0);
1579   Node* lhs = node->InputAt(0);
1580   Node* rhs = node->InputAt(1);
1581 
1582   Node* projection =
1583       graph()->NewNode(machine()->Int32MulWithOverflow(), lhs, rhs, control);
1584 
1585   Node* check = graph()->NewNode(common()->Projection(1), projection, control);
1586   control = effect =
1587       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
1588                        check, frame_state, effect, control);
1589 
1590   Node* value = graph()->NewNode(common()->Projection(0), projection, control);
1591 
1592   if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
1593     Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value, zero);
1594     Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1595                                          check_zero, control);
1596 
1597     Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero);
1598     Node* e_if_zero = effect;
1599     {
1600       // We may need to return negative zero.
1601       Node* or_inputs = graph()->NewNode(machine()->Word32Or(), lhs, rhs);
1602       Node* check_or =
1603           graph()->NewNode(machine()->Int32LessThan(), or_inputs, zero);
1604       if_zero = e_if_zero =
1605           graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
1606                            check_or, frame_state, e_if_zero, if_zero);
1607     }
1608 
1609     Node* if_not_zero = graph()->NewNode(common()->IfFalse(), branch_zero);
1610     Node* e_if_not_zero = effect;
1611 
1612     control = graph()->NewNode(common()->Merge(2), if_zero, if_not_zero);
1613     effect = graph()->NewNode(common()->EffectPhi(2), e_if_zero, e_if_not_zero,
1614                               control);
1615   }
1616 
1617   return ValueEffectControl(value, effect, control);
1618 }
1619 
1620 EffectControlLinearizer::ValueEffectControl
LowerCheckedInt32ToTaggedSigned(Node * node,Node * frame_state,Node * effect,Node * control)1621 EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(Node* node,
1622                                                          Node* frame_state,
1623                                                          Node* effect,
1624                                                          Node* control) {
1625   DCHECK(SmiValuesAre31Bits());
1626   Node* value = node->InputAt(0);
1627 
1628   Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value,
1629                                control);
1630 
1631   Node* check = graph()->NewNode(common()->Projection(1), add, control);
1632   control = effect =
1633       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
1634                        check, frame_state, effect, control);
1635 
1636   value = graph()->NewNode(common()->Projection(0), add, control);
1637 
1638   return ValueEffectControl(value, effect, control);
1639 }
1640 
1641 EffectControlLinearizer::ValueEffectControl
LowerCheckedUint32ToInt32(Node * node,Node * frame_state,Node * effect,Node * control)1642 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
1643                                                    Node* frame_state,
1644                                                    Node* effect,
1645                                                    Node* control) {
1646   Node* value = node->InputAt(0);
1647   Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max());
1648   Node* is_safe =
1649       graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int);
1650   control = effect = graph()->NewNode(
1651       common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), is_safe,
1652       frame_state, effect, control);
1653 
1654   return ValueEffectControl(value, effect, control);
1655 }
1656 
1657 EffectControlLinearizer::ValueEffectControl
LowerCheckedUint32ToTaggedSigned(Node * node,Node * frame_state,Node * effect,Node * control)1658 EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned(Node* node,
1659                                                           Node* frame_state,
1660                                                           Node* effect,
1661                                                           Node* control) {
1662   Node* value = node->InputAt(0);
1663   Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value,
1664                                  SmiMaxValueConstant());
1665   control = effect = graph()->NewNode(
1666       common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check,
1667       frame_state, effect, control);
1668   value = ChangeUint32ToSmi(value);
1669 
1670   return ValueEffectControl(value, effect, control);
1671 }
1672 
1673 EffectControlLinearizer::ValueEffectControl
BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode,Node * value,Node * frame_state,Node * effect,Node * control)1674 EffectControlLinearizer::BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode,
1675                                                     Node* value,
1676                                                     Node* frame_state,
1677                                                     Node* effect,
1678                                                     Node* control) {
1679   Node* value32 = graph()->NewNode(machine()->RoundFloat64ToInt32(), value);
1680   Node* check_same = graph()->NewNode(
1681       machine()->Float64Equal(), value,
1682       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32));
1683   control = effect = graph()->NewNode(
1684       common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecisionOrNaN),
1685       check_same, frame_state, effect, control);
1686 
1687   if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
1688     // Check if {value} is -0.
1689     Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32,
1690                                         jsgraph()->Int32Constant(0));
1691     Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1692                                          check_zero, control);
1693 
1694     Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero);
1695     Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero);
1696 
1697     // In case of 0, we need to check the high bits for the IEEE -0 pattern.
1698     Node* check_negative = graph()->NewNode(
1699         machine()->Int32LessThan(),
1700         graph()->NewNode(machine()->Float64ExtractHighWord32(), value),
1701         jsgraph()->Int32Constant(0));
1702 
1703     Node* deopt_minus_zero =
1704         graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
1705                          check_negative, frame_state, effect, if_zero);
1706 
1707     control =
1708         graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero);
1709     effect = graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect,
1710                               control);
1711   }
1712 
1713   return ValueEffectControl(value32, effect, control);
1714 }
1715 
1716 EffectControlLinearizer::ValueEffectControl
LowerCheckedFloat64ToInt32(Node * node,Node * frame_state,Node * effect,Node * control)1717 EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node,
1718                                                     Node* frame_state,
1719                                                     Node* effect,
1720                                                     Node* control) {
1721   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
1722   Node* value = node->InputAt(0);
1723 
1724   return BuildCheckedFloat64ToInt32(mode, value, frame_state, effect, control);
1725 }
1726 
1727 EffectControlLinearizer::ValueEffectControl
LowerCheckedTaggedSignedToInt32(Node * node,Node * frame_state,Node * effect,Node * control)1728 EffectControlLinearizer::LowerCheckedTaggedSignedToInt32(Node* node,
1729                                                          Node* frame_state,
1730                                                          Node* effect,
1731                                                          Node* control) {
1732   Node* value = node->InputAt(0);
1733 
1734   Node* check = ObjectIsSmi(value);
1735   control = effect =
1736       graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNotASmi),
1737                        check, frame_state, effect, control);
1738   value = ChangeSmiToInt32(value);
1739 
1740   return ValueEffectControl(value, effect, control);
1741 }
1742 
1743 EffectControlLinearizer::ValueEffectControl
LowerCheckedTaggedToInt32(Node * node,Node * frame_state,Node * effect,Node * control)1744 EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
1745                                                    Node* frame_state,
1746                                                    Node* effect,
1747                                                    Node* control) {
1748   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
1749   Node* value = node->InputAt(0);
1750 
1751   Node* check = ObjectIsSmi(value);
1752   Node* branch =
1753       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1754 
1755   // In the Smi case, just convert to int32.
1756   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1757   Node* etrue = effect;
1758   Node* vtrue = ChangeSmiToInt32(value);
1759 
1760   // In the non-Smi case, check the heap numberness, load the number and convert
1761   // to int32.
1762   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1763   Node* efalse = effect;
1764   Node* vfalse;
1765   {
1766     Node* value_map = efalse =
1767         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
1768                          value, efalse, if_false);
1769     Node* check = graph()->NewNode(machine()->WordEqual(), value_map,
1770                                    jsgraph()->HeapNumberMapConstant());
1771     if_false = efalse = graph()->NewNode(
1772         common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber), check,
1773         frame_state, efalse, if_false);
1774     vfalse = efalse = graph()->NewNode(
1775         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1776         efalse, if_false);
1777     ValueEffectControl state =
1778         BuildCheckedFloat64ToInt32(mode, vfalse, frame_state, efalse, if_false);
1779     if_false = state.control;
1780     efalse = state.effect;
1781     vfalse = state.value;
1782   }
1783 
1784   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1785   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1786   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1787                            vtrue, vfalse, control);
1788 
1789   return ValueEffectControl(value, effect, control);
1790 }
1791 
1792 EffectControlLinearizer::ValueEffectControl
BuildCheckedHeapNumberOrOddballToFloat64(CheckTaggedInputMode mode,Node * value,Node * frame_state,Node * effect,Node * control)1793 EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
1794     CheckTaggedInputMode mode, Node* value, Node* frame_state, Node* effect,
1795     Node* control) {
1796   Node* value_map = effect = graph()->NewNode(
1797       simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
1798 
1799   Node* check_number = graph()->NewNode(machine()->WordEqual(), value_map,
1800                                         jsgraph()->HeapNumberMapConstant());
1801 
1802   switch (mode) {
1803     case CheckTaggedInputMode::kNumber: {
1804       control = effect = graph()->NewNode(
1805           common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber),
1806           check_number, frame_state, effect, control);
1807       break;
1808     }
1809     case CheckTaggedInputMode::kNumberOrOddball: {
1810       Node* branch =
1811           graph()->NewNode(common()->Branch(), check_number, control);
1812 
1813       Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1814       Node* etrue = effect;
1815 
1816       Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1817       // For oddballs also contain the numeric value, let us just check that
1818       // we have an oddball here.
1819       Node* efalse = effect;
1820       Node* instance_type = efalse = graph()->NewNode(
1821           simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
1822           value_map, efalse, if_false);
1823       Node* check_oddball =
1824           graph()->NewNode(machine()->Word32Equal(), instance_type,
1825                            jsgraph()->Int32Constant(ODDBALL_TYPE));
1826       if_false = efalse = graph()->NewNode(
1827           common()->DeoptimizeUnless(DeoptimizeReason::kNotANumberOrOddball),
1828           check_oddball, frame_state, efalse, if_false);
1829       STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1830 
1831       control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1832       effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1833       break;
1834     }
1835   }
1836 
1837   value = effect = graph()->NewNode(
1838       simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1839       effect, control);
1840   return ValueEffectControl(value, effect, control);
1841 }
1842 
1843 EffectControlLinearizer::ValueEffectControl
LowerCheckedTaggedToFloat64(Node * node,Node * frame_state,Node * effect,Node * control)1844 EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
1845                                                      Node* frame_state,
1846                                                      Node* effect,
1847                                                      Node* control) {
1848   CheckTaggedInputMode mode = CheckTaggedInputModeOf(node->op());
1849   Node* value = node->InputAt(0);
1850 
1851   Node* check = ObjectIsSmi(value);
1852   Node* branch = graph()->NewNode(common()->Branch(), check, control);
1853 
1854   // In the Smi case, just convert to int32 and then float64.
1855   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1856   Node* etrue = effect;
1857   Node* vtrue = ChangeSmiToInt32(value);
1858   vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue);
1859 
1860   // Otherwise, check heap numberness and load the number.
1861   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1862   ValueEffectControl number_state = BuildCheckedHeapNumberOrOddballToFloat64(
1863       mode, value, frame_state, effect, if_false);
1864 
1865   Node* merge =
1866       graph()->NewNode(common()->Merge(2), if_true, number_state.control);
1867   Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue,
1868                                       number_state.effect, merge);
1869   Node* result =
1870       graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), vtrue,
1871                        number_state.value, merge);
1872 
1873   return ValueEffectControl(result, effect_phi, merge);
1874 }
1875 
1876 EffectControlLinearizer::ValueEffectControl
LowerCheckedTaggedToTaggedSigned(Node * node,Node * frame_state,Node * effect,Node * control)1877 EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(Node* node,
1878                                                           Node* frame_state,
1879                                                           Node* effect,
1880                                                           Node* control) {
1881   Node* value = node->InputAt(0);
1882 
1883   Node* check = ObjectIsSmi(value);
1884   control = effect =
1885       graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNotASmi),
1886                        check, frame_state, effect, control);
1887 
1888   return ValueEffectControl(value, effect, control);
1889 }
1890 
1891 EffectControlLinearizer::ValueEffectControl
LowerCheckedTaggedToTaggedPointer(Node * node,Node * frame_state,Node * effect,Node * control)1892 EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer(Node* node,
1893                                                            Node* frame_state,
1894                                                            Node* effect,
1895                                                            Node* control) {
1896   Node* value = node->InputAt(0);
1897 
1898   Node* check = ObjectIsSmi(value);
1899   control = effect =
1900       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check,
1901                        frame_state, effect, control);
1902 
1903   return ValueEffectControl(value, effect, control);
1904 }
1905 
1906 EffectControlLinearizer::ValueEffectControl
LowerTruncateTaggedToWord32(Node * node,Node * effect,Node * control)1907 EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect,
1908                                                      Node* control) {
1909   Node* value = node->InputAt(0);
1910 
1911   Node* check = ObjectIsSmi(value);
1912   Node* branch =
1913       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1914 
1915   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1916   Node* etrue = effect;
1917   Node* vtrue = ChangeSmiToInt32(value);
1918 
1919   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1920   Node* efalse = effect;
1921   Node* vfalse;
1922   {
1923     STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1924     vfalse = efalse = graph()->NewNode(
1925         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1926         efalse, if_false);
1927     vfalse = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse);
1928   }
1929 
1930   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1931   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1932   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1933                            vtrue, vfalse, control);
1934 
1935   return ValueEffectControl(value, effect, control);
1936 }
1937 
1938 EffectControlLinearizer::ValueEffectControl
LowerCheckedTruncateTaggedToWord32(Node * node,Node * frame_state,Node * effect,Node * control)1939 EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32(Node* node,
1940                                                             Node* frame_state,
1941                                                             Node* effect,
1942                                                             Node* control) {
1943   Node* value = node->InputAt(0);
1944 
1945   Node* check = ObjectIsSmi(value);
1946   Node* branch =
1947       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1948 
1949   // In the Smi case, just convert to int32.
1950   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1951   Node* etrue = effect;
1952   Node* vtrue = ChangeSmiToInt32(value);
1953 
1954   // Otherwise, check that it's a heap number or oddball and truncate the value
1955   // to int32.
1956   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1957   ValueEffectControl false_state = BuildCheckedHeapNumberOrOddballToFloat64(
1958       CheckTaggedInputMode::kNumberOrOddball, value, frame_state, effect,
1959       if_false);
1960   false_state.value =
1961       graph()->NewNode(machine()->TruncateFloat64ToWord32(), false_state.value);
1962 
1963   Node* merge =
1964       graph()->NewNode(common()->Merge(2), if_true, false_state.control);
1965   Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue,
1966                                       false_state.effect, merge);
1967   Node* result =
1968       graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue,
1969                        false_state.value, merge);
1970 
1971   return ValueEffectControl(result, effect_phi, merge);
1972 }
1973 
1974 EffectControlLinearizer::ValueEffectControl
LowerObjectIsCallable(Node * node,Node * effect,Node * control)1975 EffectControlLinearizer::LowerObjectIsCallable(Node* node, Node* effect,
1976                                                Node* control) {
1977   Node* value = node->InputAt(0);
1978 
1979   Node* check = ObjectIsSmi(value);
1980   Node* branch =
1981       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
1982 
1983   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1984   Node* etrue = effect;
1985   Node* vtrue = jsgraph()->Int32Constant(0);
1986 
1987   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1988   Node* efalse = effect;
1989   Node* vfalse;
1990   {
1991     Node* value_map = efalse =
1992         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
1993                          value, efalse, if_false);
1994     Node* value_bit_field = efalse = graph()->NewNode(
1995         simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
1996         efalse, if_false);
1997     vfalse = graph()->NewNode(
1998         machine()->Word32Equal(),
1999         jsgraph()->Int32Constant(1 << Map::kIsCallable),
2000         graph()->NewNode(
2001             machine()->Word32And(), value_bit_field,
2002             jsgraph()->Int32Constant((1 << Map::kIsCallable) |
2003                                      (1 << Map::kIsUndetectable))));
2004   }
2005 
2006   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
2007   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
2008   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
2009                            vfalse, control);
2010 
2011   return ValueEffectControl(value, effect, control);
2012 }
2013 
2014 EffectControlLinearizer::ValueEffectControl
LowerObjectIsNumber(Node * node,Node * effect,Node * control)2015 EffectControlLinearizer::LowerObjectIsNumber(Node* node, Node* effect,
2016                                              Node* control) {
2017   Node* value = node->InputAt(0);
2018 
2019   Node* check = ObjectIsSmi(value);
2020   Node* branch = graph()->NewNode(common()->Branch(), check, control);
2021 
2022   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
2023   Node* etrue = effect;
2024   Node* vtrue = jsgraph()->Int32Constant(1);
2025 
2026   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
2027   Node* efalse = effect;
2028   Node* vfalse;
2029   {
2030     Node* value_map = efalse =
2031         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2032                          value, efalse, if_false);
2033     vfalse = graph()->NewNode(machine()->WordEqual(), value_map,
2034                               jsgraph()->HeapNumberMapConstant());
2035   }
2036 
2037   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
2038   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
2039   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
2040                            vfalse, control);
2041 
2042   return ValueEffectControl(value, effect, control);
2043 }
2044 
2045 EffectControlLinearizer::ValueEffectControl
LowerObjectIsReceiver(Node * node,Node * effect,Node * control)2046 EffectControlLinearizer::LowerObjectIsReceiver(Node* node, Node* effect,
2047                                                Node* control) {
2048   Node* value = node->InputAt(0);
2049 
2050   Node* check = ObjectIsSmi(value);
2051   Node* branch =
2052       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
2053 
2054   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
2055   Node* etrue = effect;
2056   Node* vtrue = jsgraph()->Int32Constant(0);
2057 
2058   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
2059   Node* efalse = effect;
2060   Node* vfalse;
2061   {
2062     STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
2063     Node* value_map = efalse =
2064         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2065                          value, efalse, if_false);
2066     Node* value_instance_type = efalse = graph()->NewNode(
2067         simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
2068         efalse, if_false);
2069     vfalse = graph()->NewNode(machine()->Uint32LessThanOrEqual(),
2070                               jsgraph()->Uint32Constant(FIRST_JS_RECEIVER_TYPE),
2071                               value_instance_type);
2072   }
2073 
2074   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
2075   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
2076   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
2077                            vfalse, control);
2078 
2079   return ValueEffectControl(value, effect, control);
2080 }
2081 
2082 EffectControlLinearizer::ValueEffectControl
LowerObjectIsSmi(Node * node,Node * effect,Node * control)2083 EffectControlLinearizer::LowerObjectIsSmi(Node* node, Node* effect,
2084                                           Node* control) {
2085   Node* value = node->InputAt(0);
2086   value = ObjectIsSmi(value);
2087   return ValueEffectControl(value, effect, control);
2088 }
2089 
2090 EffectControlLinearizer::ValueEffectControl
LowerObjectIsString(Node * node,Node * effect,Node * control)2091 EffectControlLinearizer::LowerObjectIsString(Node* node, Node* effect,
2092                                              Node* control) {
2093   Node* value = node->InputAt(0);
2094 
2095   Node* check = ObjectIsSmi(value);
2096   Node* branch =
2097       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
2098 
2099   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
2100   Node* etrue = effect;
2101   Node* vtrue = jsgraph()->Int32Constant(0);
2102 
2103   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
2104   Node* efalse = effect;
2105   Node* vfalse;
2106   {
2107     Node* value_map = efalse =
2108         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2109                          value, efalse, if_false);
2110     Node* value_instance_type = efalse = graph()->NewNode(
2111         simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
2112         efalse, if_false);
2113     vfalse = graph()->NewNode(machine()->Uint32LessThan(), value_instance_type,
2114                               jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE));
2115   }
2116 
2117   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
2118   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
2119   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
2120                            vfalse, control);
2121 
2122   return ValueEffectControl(value, effect, control);
2123 }
2124 
2125 EffectControlLinearizer::ValueEffectControl
LowerObjectIsUndetectable(Node * node,Node * effect,Node * control)2126 EffectControlLinearizer::LowerObjectIsUndetectable(Node* node, Node* effect,
2127                                                    Node* control) {
2128   Node* value = node->InputAt(0);
2129 
2130   Node* check = ObjectIsSmi(value);
2131   Node* branch =
2132       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
2133 
2134   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
2135   Node* etrue = effect;
2136   Node* vtrue = jsgraph()->Int32Constant(0);
2137 
2138   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
2139   Node* efalse = effect;
2140   Node* vfalse;
2141   {
2142     Node* value_map = efalse =
2143         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2144                          value, efalse, if_false);
2145     Node* value_bit_field = efalse = graph()->NewNode(
2146         simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
2147         efalse, if_false);
2148     vfalse = graph()->NewNode(
2149         machine()->Word32Equal(),
2150         graph()->NewNode(
2151             machine()->Word32Equal(), jsgraph()->Int32Constant(0),
2152             graph()->NewNode(
2153                 machine()->Word32And(), value_bit_field,
2154                 jsgraph()->Int32Constant(1 << Map::kIsUndetectable))),
2155         jsgraph()->Int32Constant(0));
2156   }
2157 
2158   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
2159   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
2160   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
2161                            vfalse, control);
2162 
2163   return ValueEffectControl(value, effect, control);
2164 }
2165 
2166 EffectControlLinearizer::ValueEffectControl
LowerArrayBufferWasNeutered(Node * node,Node * effect,Node * control)2167 EffectControlLinearizer::LowerArrayBufferWasNeutered(Node* node, Node* effect,
2168                                                      Node* control) {
2169   Node* value = node->InputAt(0);
2170 
2171   Node* value_bit_field = effect = graph()->NewNode(
2172       simplified()->LoadField(AccessBuilder::ForJSArrayBufferBitField()), value,
2173       effect, control);
2174   value = graph()->NewNode(
2175       machine()->Word32Equal(),
2176       graph()->NewNode(machine()->Word32Equal(),
2177                        graph()->NewNode(machine()->Word32And(), value_bit_field,
2178                                         jsgraph()->Int32Constant(
2179                                             JSArrayBuffer::WasNeutered::kMask)),
2180                        jsgraph()->Int32Constant(0)),
2181       jsgraph()->Int32Constant(0));
2182 
2183   return ValueEffectControl(value, effect, control);
2184 }
2185 
2186 EffectControlLinearizer::ValueEffectControl
LowerStringCharCodeAt(Node * node,Node * effect,Node * control)2187 EffectControlLinearizer::LowerStringCharCodeAt(Node* node, Node* effect,
2188                                                Node* control) {
2189   Node* subject = node->InputAt(0);
2190   Node* index = node->InputAt(1);
2191 
2192   // We may need to loop several times for ConsString/SlicedString {subject}s.
2193   Node* loop =
2194       graph()->NewNode(common()->Loop(4), control, control, control, control);
2195   Node* lsubject =
2196       graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 4),
2197                        subject, subject, subject, subject, loop);
2198   Node* lindex =
2199       graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 4), index,
2200                        index, index, index, loop);
2201   Node* leffect = graph()->NewNode(common()->EffectPhi(4), effect, effect,
2202                                    effect, effect, loop);
2203 
2204   control = loop;
2205   effect = leffect;
2206 
2207   // Determine the instance type of {lsubject}.
2208   Node* lsubject_map = effect =
2209       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2210                        lsubject, effect, control);
2211   Node* lsubject_instance_type = effect = graph()->NewNode(
2212       simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
2213       lsubject_map, effect, control);
2214 
2215   // Check if {lsubject} is a SeqString.
2216   Node* check0 = graph()->NewNode(
2217       machine()->Word32Equal(),
2218       graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2219                        jsgraph()->Int32Constant(kStringRepresentationMask)),
2220       jsgraph()->Int32Constant(kSeqStringTag));
2221   Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
2222 
2223   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2224   Node* etrue0 = effect;
2225   Node* vtrue0;
2226   {
2227     // Check if the {lsubject} is a TwoByteSeqString or a OneByteSeqString.
2228     Node* check1 = graph()->NewNode(
2229         machine()->Word32Equal(),
2230         graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2231                          jsgraph()->Int32Constant(kStringEncodingMask)),
2232         jsgraph()->Int32Constant(kTwoByteStringTag));
2233     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
2234 
2235     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2236     Node* etrue1 = etrue0;
2237     Node* vtrue1 = etrue1 =
2238         graph()->NewNode(simplified()->LoadElement(
2239                              AccessBuilder::ForSeqTwoByteStringCharacter()),
2240                          lsubject, lindex, etrue1, if_true1);
2241 
2242     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2243     Node* efalse1 = etrue0;
2244     Node* vfalse1 = efalse1 =
2245         graph()->NewNode(simplified()->LoadElement(
2246                              AccessBuilder::ForSeqOneByteStringCharacter()),
2247                          lsubject, lindex, efalse1, if_false1);
2248 
2249     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2250     etrue0 =
2251         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
2252     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2253                               vtrue1, vfalse1, if_true0);
2254   }
2255 
2256   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2257   Node* efalse0 = effect;
2258   Node* vfalse0;
2259   {
2260     // Check if the {lsubject} is a ConsString.
2261     Node* check1 = graph()->NewNode(
2262         machine()->Word32Equal(),
2263         graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2264                          jsgraph()->Int32Constant(kStringRepresentationMask)),
2265         jsgraph()->Int32Constant(kConsStringTag));
2266     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
2267 
2268     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2269     Node* etrue1 = efalse0;
2270     {
2271       // Load the right hand side of the {lsubject} ConsString.
2272       Node* lsubject_second = etrue1 = graph()->NewNode(
2273           simplified()->LoadField(AccessBuilder::ForConsStringSecond()),
2274           lsubject, etrue1, if_true1);
2275 
2276       // Check whether the right hand side is the empty string (i.e. if
2277       // this is really a flat string in a cons string). If that is not
2278       // the case we flatten the string first.
2279       Node* check2 = graph()->NewNode(machine()->WordEqual(), lsubject_second,
2280                                       jsgraph()->EmptyStringConstant());
2281       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
2282                                        check2, if_true1);
2283 
2284       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
2285       Node* etrue2 = etrue1;
2286       Node* vtrue2 = etrue2 = graph()->NewNode(
2287           simplified()->LoadField(AccessBuilder::ForConsStringFirst()),
2288           lsubject, etrue2, if_true2);
2289 
2290       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2291       Node* efalse2 = etrue1;
2292       Node* vfalse2;
2293       {
2294         // Flatten the {lsubject} ConsString first.
2295         Operator::Properties properties =
2296             Operator::kNoDeopt | Operator::kNoThrow;
2297         Runtime::FunctionId id = Runtime::kFlattenString;
2298         CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
2299             graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
2300         vfalse2 = efalse2 = graph()->NewNode(
2301             common()->Call(desc), jsgraph()->CEntryStubConstant(1), lsubject,
2302             jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
2303             jsgraph()->Int32Constant(1), jsgraph()->NoContextConstant(),
2304             efalse2, if_false2);
2305       }
2306 
2307       // Retry the {loop} with the new subject.
2308       loop->ReplaceInput(1, if_true2);
2309       lindex->ReplaceInput(1, lindex);
2310       leffect->ReplaceInput(1, etrue2);
2311       lsubject->ReplaceInput(1, vtrue2);
2312       loop->ReplaceInput(2, if_false2);
2313       lindex->ReplaceInput(2, lindex);
2314       leffect->ReplaceInput(2, efalse2);
2315       lsubject->ReplaceInput(2, vfalse2);
2316     }
2317 
2318     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2319     Node* efalse1 = efalse0;
2320     Node* vfalse1;
2321     {
2322       // Check if the {lsubject} is an ExternalString.
2323       Node* check2 = graph()->NewNode(
2324           machine()->Word32Equal(),
2325           graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2326                            jsgraph()->Int32Constant(kStringRepresentationMask)),
2327           jsgraph()->Int32Constant(kExternalStringTag));
2328       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
2329                                        check2, if_false1);
2330 
2331       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
2332       Node* etrue2 = efalse1;
2333       Node* vtrue2;
2334       {
2335         // Check if the {lsubject} is a short external string.
2336         Node* check3 = graph()->NewNode(
2337             machine()->Word32Equal(),
2338             graph()->NewNode(
2339                 machine()->Word32And(), lsubject_instance_type,
2340                 jsgraph()->Int32Constant(kShortExternalStringMask)),
2341             jsgraph()->Int32Constant(0));
2342         Node* branch3 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
2343                                          check3, if_true2);
2344 
2345         Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3);
2346         Node* etrue3 = etrue2;
2347         Node* vtrue3;
2348         {
2349           // Load the actual resource data from the {lsubject}.
2350           Node* lsubject_resource_data = etrue3 = graph()->NewNode(
2351               simplified()->LoadField(
2352                   AccessBuilder::ForExternalStringResourceData()),
2353               lsubject, etrue3, if_true3);
2354 
2355           // Check if the {lsubject} is a TwoByteExternalString or a
2356           // OneByteExternalString.
2357           Node* check4 = graph()->NewNode(
2358               machine()->Word32Equal(),
2359               graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
2360                                jsgraph()->Int32Constant(kStringEncodingMask)),
2361               jsgraph()->Int32Constant(kTwoByteStringTag));
2362           Node* branch4 =
2363               graph()->NewNode(common()->Branch(), check4, if_true3);
2364 
2365           Node* if_true4 = graph()->NewNode(common()->IfTrue(), branch4);
2366           Node* etrue4 = etrue3;
2367           Node* vtrue4 = etrue4 = graph()->NewNode(
2368               simplified()->LoadElement(
2369                   AccessBuilder::ForExternalTwoByteStringCharacter()),
2370               lsubject_resource_data, lindex, etrue4, if_true4);
2371 
2372           Node* if_false4 = graph()->NewNode(common()->IfFalse(), branch4);
2373           Node* efalse4 = etrue3;
2374           Node* vfalse4 = efalse4 = graph()->NewNode(
2375               simplified()->LoadElement(
2376                   AccessBuilder::ForExternalOneByteStringCharacter()),
2377               lsubject_resource_data, lindex, efalse4, if_false4);
2378 
2379           if_true3 = graph()->NewNode(common()->Merge(2), if_true4, if_false4);
2380           etrue3 = graph()->NewNode(common()->EffectPhi(2), etrue4, efalse4,
2381                                     if_true3);
2382           vtrue3 =
2383               graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2384                                vtrue4, vfalse4, if_true3);
2385         }
2386 
2387         Node* if_false3 = graph()->NewNode(common()->IfFalse(), branch3);
2388         Node* efalse3 = etrue2;
2389         Node* vfalse3;
2390         {
2391           // The {lsubject} might be compressed, call the runtime.
2392           Operator::Properties properties =
2393               Operator::kNoDeopt | Operator::kNoThrow;
2394           Runtime::FunctionId id = Runtime::kExternalStringGetChar;
2395           CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
2396               graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
2397           vfalse3 = efalse3 = graph()->NewNode(
2398               common()->Call(desc), jsgraph()->CEntryStubConstant(1), lsubject,
2399               ChangeInt32ToSmi(lindex),
2400               jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
2401               jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(),
2402               efalse3, if_false3);
2403           vfalse3 = ChangeSmiToInt32(vfalse3);
2404         }
2405 
2406         if_true2 = graph()->NewNode(common()->Merge(2), if_true3, if_false3);
2407         etrue2 =
2408             graph()->NewNode(common()->EffectPhi(2), etrue3, efalse3, if_true2);
2409         vtrue2 =
2410             graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2411                              vtrue3, vfalse3, if_true2);
2412       }
2413 
2414       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2415       Node* efalse2 = efalse1;
2416       {
2417         // The {lsubject} is a SlicedString, continue with its parent.
2418         Node* lsubject_parent = efalse2 = graph()->NewNode(
2419             simplified()->LoadField(AccessBuilder::ForSlicedStringParent()),
2420             lsubject, efalse2, if_false2);
2421         Node* lsubject_offset = efalse2 = graph()->NewNode(
2422             simplified()->LoadField(AccessBuilder::ForSlicedStringOffset()),
2423             lsubject, efalse2, if_false2);
2424         Node* lsubject_index = graph()->NewNode(
2425             machine()->Int32Add(), lindex, ChangeSmiToInt32(lsubject_offset));
2426 
2427         // Retry the {loop} with the parent subject.
2428         loop->ReplaceInput(3, if_false2);
2429         leffect->ReplaceInput(3, efalse2);
2430         lindex->ReplaceInput(3, lsubject_index);
2431         lsubject->ReplaceInput(3, lsubject_parent);
2432       }
2433 
2434       if_false1 = if_true2;
2435       efalse1 = etrue2;
2436       vfalse1 = vtrue2;
2437     }
2438 
2439     if_false0 = if_false1;
2440     efalse0 = efalse1;
2441     vfalse0 = vfalse1;
2442   }
2443 
2444   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2445   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2446   Node* value =
2447       graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0,
2448                        vfalse0, control);
2449 
2450   return ValueEffectControl(value, effect, control);
2451 }
2452 
2453 EffectControlLinearizer::ValueEffectControl
LowerStringFromCharCode(Node * node,Node * effect,Node * control)2454 EffectControlLinearizer::LowerStringFromCharCode(Node* node, Node* effect,
2455                                                  Node* control) {
2456   Node* value = node->InputAt(0);
2457 
2458   // Compute the character code.
2459   Node* code =
2460       graph()->NewNode(machine()->Word32And(), value,
2461                        jsgraph()->Int32Constant(String::kMaxUtf16CodeUnit));
2462 
2463   // Check if the {code} is a one-byte char code.
2464   Node* check0 =
2465       graph()->NewNode(machine()->Int32LessThanOrEqual(), code,
2466                        jsgraph()->Int32Constant(String::kMaxOneByteCharCode));
2467   Node* branch0 =
2468       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
2469 
2470   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2471   Node* efalse0 = effect;
2472 
2473   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2474   Node* etrue0 = effect;
2475 
2476   // Load the isolate wide single character string cache.
2477   Node* cache =
2478       jsgraph()->HeapConstant(factory()->single_character_string_cache());
2479 
2480   // Compute the {cache} index for {code}.
2481   Node* index = machine()->Is32()
2482                     ? code
2483                     : graph()->NewNode(machine()->ChangeUint32ToUint64(), code);
2484 
2485   // Check if we have an entry for the {code} in the single character string
2486   // cache already.
2487   Node* entry = etrue0 = graph()->NewNode(
2488       simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache,
2489       index, etrue0, if_true0);
2490 
2491   Node* check1 = graph()->NewNode(machine()->WordEqual(), entry,
2492                                   jsgraph()->UndefinedConstant());
2493   Node* branch1 =
2494       graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, if_true0);
2495 
2496   // Use the {entry} from the {cache}.
2497   Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2498   Node* efalse1 = etrue0;
2499   Node* vfalse1 = entry;
2500 
2501   // Let %StringFromCharCode handle this case.
2502   // TODO(turbofan): At some point we may consider adding a stub for this
2503   // deferred case, so that we don't need to call to C++ here.
2504   Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2505   Node* etrue1 = etrue0;
2506   Node* vtrue1;
2507   {
2508     if_true1 = graph()->NewNode(common()->Merge(2), if_true1, if_false0);
2509     etrue1 =
2510         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse0, if_true1);
2511     Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
2512     Runtime::FunctionId id = Runtime::kStringCharFromCode;
2513     CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
2514         graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
2515     vtrue1 = etrue1 = graph()->NewNode(
2516         common()->Call(desc), jsgraph()->CEntryStubConstant(1),
2517         ChangeInt32ToSmi(code),
2518         jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
2519         jsgraph()->Int32Constant(1), jsgraph()->NoContextConstant(), etrue1,
2520         if_true1);
2521   }
2522 
2523   control = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2524   effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control);
2525   value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2526                            vtrue1, vfalse1, control);
2527 
2528   return ValueEffectControl(value, effect, control);
2529 }
2530 
2531 EffectControlLinearizer::ValueEffectControl
LowerStringFromCodePoint(Node * node,Node * effect,Node * control)2532 EffectControlLinearizer::LowerStringFromCodePoint(Node* node, Node* effect,
2533                                                   Node* control) {
2534   Node* value = node->InputAt(0);
2535   Node* code = value;
2536 
2537   Node* etrue0 = effect;
2538   Node* vtrue0;
2539 
2540   // Check if the {code} is a single code unit
2541   Node* check0 = graph()->NewNode(machine()->Uint32LessThanOrEqual(), code,
2542                                   jsgraph()->Uint32Constant(0xFFFF));
2543   Node* branch0 =
2544       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
2545 
2546   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2547   {
2548     // Check if the {code} is a one byte character
2549     Node* check1 = graph()->NewNode(
2550         machine()->Uint32LessThanOrEqual(), code,
2551         jsgraph()->Uint32Constant(String::kMaxOneByteCharCode));
2552     Node* branch1 =
2553         graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0);
2554 
2555     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2556     Node* etrue1 = etrue0;
2557     Node* vtrue1;
2558     {
2559       // Load the isolate wide single character string cache.
2560       Node* cache =
2561           jsgraph()->HeapConstant(factory()->single_character_string_cache());
2562 
2563       // Compute the {cache} index for {code}.
2564       Node* index =
2565           machine()->Is32()
2566               ? code
2567               : graph()->NewNode(machine()->ChangeUint32ToUint64(), code);
2568 
2569       // Check if we have an entry for the {code} in the single character string
2570       // cache already.
2571       Node* entry = etrue1 = graph()->NewNode(
2572           simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()),
2573           cache, index, etrue1, if_true1);
2574 
2575       Node* check2 = graph()->NewNode(machine()->WordEqual(), entry,
2576                                       jsgraph()->UndefinedConstant());
2577       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
2578                                        check2, if_true1);
2579 
2580       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
2581       Node* etrue2 = etrue1;
2582       Node* vtrue2;
2583       {
2584         // Allocate a new SeqOneByteString for {code}.
2585         vtrue2 = etrue2 = graph()->NewNode(
2586             simplified()->Allocate(NOT_TENURED),
2587             jsgraph()->Int32Constant(SeqOneByteString::SizeFor(1)), etrue2,
2588             if_true2);
2589         etrue2 = graph()->NewNode(
2590             simplified()->StoreField(AccessBuilder::ForMap()), vtrue2,
2591             jsgraph()->HeapConstant(factory()->one_byte_string_map()), etrue2,
2592             if_true2);
2593         etrue2 = graph()->NewNode(
2594             simplified()->StoreField(AccessBuilder::ForNameHashField()), vtrue2,
2595             jsgraph()->IntPtrConstant(Name::kEmptyHashField), etrue2, if_true2);
2596         etrue2 = graph()->NewNode(
2597             simplified()->StoreField(AccessBuilder::ForStringLength()), vtrue2,
2598             jsgraph()->SmiConstant(1), etrue2, if_true2);
2599         etrue2 = graph()->NewNode(
2600             machine()->Store(StoreRepresentation(MachineRepresentation::kWord8,
2601                                                  kNoWriteBarrier)),
2602             vtrue2, jsgraph()->IntPtrConstant(SeqOneByteString::kHeaderSize -
2603                                               kHeapObjectTag),
2604             code, etrue2, if_true2);
2605 
2606         // Remember it in the {cache}.
2607         etrue2 = graph()->NewNode(
2608             simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()),
2609             cache, index, vtrue2, etrue2, if_true2);
2610       }
2611 
2612       // Use the {entry} from the {cache}.
2613       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2614       Node* efalse2 = etrue0;
2615       Node* vfalse2 = entry;
2616 
2617       if_true1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
2618       etrue1 =
2619           graph()->NewNode(common()->EffectPhi(2), etrue2, efalse2, if_true1);
2620       vtrue1 =
2621           graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2622                            vtrue2, vfalse2, if_true1);
2623     }
2624 
2625     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2626     Node* efalse1 = effect;
2627     Node* vfalse1;
2628     {
2629       // Allocate a new SeqTwoByteString for {code}.
2630       vfalse1 = efalse1 = graph()->NewNode(
2631           simplified()->Allocate(NOT_TENURED),
2632           jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(1)), efalse1,
2633           if_false1);
2634       efalse1 = graph()->NewNode(
2635           simplified()->StoreField(AccessBuilder::ForMap()), vfalse1,
2636           jsgraph()->HeapConstant(factory()->string_map()), efalse1, if_false1);
2637       efalse1 = graph()->NewNode(
2638           simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse1,
2639           jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse1, if_false1);
2640       efalse1 = graph()->NewNode(
2641           simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse1,
2642           jsgraph()->SmiConstant(1), efalse1, if_false1);
2643       efalse1 = graph()->NewNode(
2644           machine()->Store(StoreRepresentation(MachineRepresentation::kWord16,
2645                                                kNoWriteBarrier)),
2646           vfalse1, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize -
2647                                              kHeapObjectTag),
2648           code, efalse1, if_false1);
2649     }
2650 
2651     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2652     etrue0 =
2653         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
2654     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2655                               vtrue1, vfalse1, if_true0);
2656   }
2657 
2658   // Generate surrogate pair string
2659   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2660   Node* efalse0 = effect;
2661   Node* vfalse0;
2662   {
2663     switch (UnicodeEncodingOf(node->op())) {
2664       case UnicodeEncoding::UTF16:
2665         break;
2666 
2667       case UnicodeEncoding::UTF32: {
2668         // Convert UTF32 to UTF16 code units, and store as a 32 bit word.
2669         Node* lead_offset = jsgraph()->Int32Constant(0xD800 - (0x10000 >> 10));
2670 
2671         // lead = (codepoint >> 10) + LEAD_OFFSET
2672         Node* lead =
2673             graph()->NewNode(machine()->Int32Add(),
2674                              graph()->NewNode(machine()->Word32Shr(), code,
2675                                               jsgraph()->Int32Constant(10)),
2676                              lead_offset);
2677 
2678         // trail = (codepoint & 0x3FF) + 0xDC00;
2679         Node* trail =
2680             graph()->NewNode(machine()->Int32Add(),
2681                              graph()->NewNode(machine()->Word32And(), code,
2682                                               jsgraph()->Int32Constant(0x3FF)),
2683                              jsgraph()->Int32Constant(0xDC00));
2684 
2685         // codpoint = (trail << 16) | lead;
2686         code = graph()->NewNode(machine()->Word32Or(),
2687                                 graph()->NewNode(machine()->Word32Shl(), trail,
2688                                                  jsgraph()->Int32Constant(16)),
2689                                 lead);
2690         break;
2691       }
2692     }
2693 
2694     // Allocate a new SeqTwoByteString for {code}.
2695     vfalse0 = efalse0 =
2696         graph()->NewNode(simplified()->Allocate(NOT_TENURED),
2697                          jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(2)),
2698                          efalse0, if_false0);
2699     efalse0 = graph()->NewNode(
2700         simplified()->StoreField(AccessBuilder::ForMap()), vfalse0,
2701         jsgraph()->HeapConstant(factory()->string_map()), efalse0, if_false0);
2702     efalse0 = graph()->NewNode(
2703         simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse0,
2704         jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse0, if_false0);
2705     efalse0 = graph()->NewNode(
2706         simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse0,
2707         jsgraph()->SmiConstant(2), efalse0, if_false0);
2708     efalse0 = graph()->NewNode(
2709         machine()->Store(StoreRepresentation(MachineRepresentation::kWord32,
2710                                              kNoWriteBarrier)),
2711         vfalse0, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize -
2712                                            kHeapObjectTag),
2713         code, efalse0, if_false0);
2714   }
2715 
2716   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2717   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2718   value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2719                            vtrue0, vfalse0, control);
2720 
2721   return ValueEffectControl(value, effect, control);
2722 }
2723 
2724 EffectControlLinearizer::ValueEffectControl
LowerStringComparison(Callable const & callable,Node * node,Node * effect,Node * control)2725 EffectControlLinearizer::LowerStringComparison(Callable const& callable,
2726                                                Node* node, Node* effect,
2727                                                Node* control) {
2728   Operator::Properties properties = Operator::kEliminatable;
2729   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
2730   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2731       isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
2732   node->InsertInput(graph()->zone(), 0,
2733                     jsgraph()->HeapConstant(callable.code()));
2734   node->AppendInput(graph()->zone(), jsgraph()->NoContextConstant());
2735   node->AppendInput(graph()->zone(), effect);
2736   NodeProperties::ChangeOp(node, common()->Call(desc));
2737   return ValueEffectControl(node, node, control);
2738 }
2739 
2740 EffectControlLinearizer::ValueEffectControl
LowerStringEqual(Node * node,Node * effect,Node * control)2741 EffectControlLinearizer::LowerStringEqual(Node* node, Node* effect,
2742                                           Node* control) {
2743   return LowerStringComparison(CodeFactory::StringEqual(isolate()), node,
2744                                effect, control);
2745 }
2746 
2747 EffectControlLinearizer::ValueEffectControl
LowerStringLessThan(Node * node,Node * effect,Node * control)2748 EffectControlLinearizer::LowerStringLessThan(Node* node, Node* effect,
2749                                              Node* control) {
2750   return LowerStringComparison(CodeFactory::StringLessThan(isolate()), node,
2751                                effect, control);
2752 }
2753 
2754 EffectControlLinearizer::ValueEffectControl
LowerStringLessThanOrEqual(Node * node,Node * effect,Node * control)2755 EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node, Node* effect,
2756                                                     Node* control) {
2757   return LowerStringComparison(CodeFactory::StringLessThanOrEqual(isolate()),
2758                                node, effect, control);
2759 }
2760 
2761 EffectControlLinearizer::ValueEffectControl
LowerCheckFloat64Hole(Node * node,Node * frame_state,Node * effect,Node * control)2762 EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, Node* frame_state,
2763                                                Node* effect, Node* control) {
2764   // If we reach this point w/o eliminating the {node} that's marked
2765   // with allow-return-hole, we cannot do anything, so just deoptimize
2766   // in case of the hole NaN (similar to Crankshaft).
2767   Node* value = node->InputAt(0);
2768   Node* check = graph()->NewNode(
2769       machine()->Word32Equal(),
2770       graph()->NewNode(machine()->Float64ExtractHighWord32(), value),
2771       jsgraph()->Int32Constant(kHoleNanUpper32));
2772   control = effect =
2773       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kHole), check,
2774                        frame_state, effect, control);
2775 
2776   return ValueEffectControl(value, effect, control);
2777 }
2778 
2779 EffectControlLinearizer::ValueEffectControl
LowerCheckTaggedHole(Node * node,Node * frame_state,Node * effect,Node * control)2780 EffectControlLinearizer::LowerCheckTaggedHole(Node* node, Node* frame_state,
2781                                               Node* effect, Node* control) {
2782   Node* value = node->InputAt(0);
2783   Node* check = graph()->NewNode(machine()->WordEqual(), value,
2784                                  jsgraph()->TheHoleConstant());
2785   control = effect =
2786       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kHole), check,
2787                        frame_state, effect, control);
2788 
2789   return ValueEffectControl(value, effect, control);
2790 }
2791 
2792 EffectControlLinearizer::ValueEffectControl
LowerConvertTaggedHoleToUndefined(Node * node,Node * effect,Node * control)2793 EffectControlLinearizer::LowerConvertTaggedHoleToUndefined(Node* node,
2794                                                            Node* effect,
2795                                                            Node* control) {
2796   Node* value = node->InputAt(0);
2797   Node* check = graph()->NewNode(machine()->WordEqual(), value,
2798                                  jsgraph()->TheHoleConstant());
2799   Node* branch =
2800       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
2801 
2802   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
2803   Node* vtrue = jsgraph()->UndefinedConstant();
2804 
2805   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
2806   Node* vfalse = value;
2807 
2808   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
2809   value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2810                            vtrue, vfalse, control);
2811 
2812   return ValueEffectControl(value, effect, control);
2813 }
2814 
2815 EffectControlLinearizer::ValueEffectControl
AllocateHeapNumberWithValue(Node * value,Node * effect,Node * control)2816 EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect,
2817                                                      Node* control) {
2818   Node* result = effect = graph()->NewNode(
2819       simplified()->Allocate(NOT_TENURED),
2820       jsgraph()->Int32Constant(HeapNumber::kSize), effect, control);
2821   effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
2822                             result, jsgraph()->HeapNumberMapConstant(), effect,
2823                             control);
2824   effect = graph()->NewNode(
2825       simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), result,
2826       value, effect, control);
2827   return ValueEffectControl(result, effect, control);
2828 }
2829 
ChangeInt32ToSmi(Node * value)2830 Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) {
2831   if (machine()->Is64()) {
2832     value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value);
2833   }
2834   return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
2835 }
2836 
ChangeUint32ToSmi(Node * value)2837 Node* EffectControlLinearizer::ChangeUint32ToSmi(Node* value) {
2838   if (machine()->Is64()) {
2839     value = graph()->NewNode(machine()->ChangeUint32ToUint64(), value);
2840   }
2841   return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
2842 }
2843 
ChangeInt32ToFloat64(Node * value)2844 Node* EffectControlLinearizer::ChangeInt32ToFloat64(Node* value) {
2845   return graph()->NewNode(machine()->ChangeInt32ToFloat64(), value);
2846 }
2847 
ChangeUint32ToFloat64(Node * value)2848 Node* EffectControlLinearizer::ChangeUint32ToFloat64(Node* value) {
2849   return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value);
2850 }
2851 
ChangeSmiToInt32(Node * value)2852 Node* EffectControlLinearizer::ChangeSmiToInt32(Node* value) {
2853   value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
2854   if (machine()->Is64()) {
2855     value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value);
2856   }
2857   return value;
2858 }
ObjectIsSmi(Node * value)2859 Node* EffectControlLinearizer::ObjectIsSmi(Node* value) {
2860   return graph()->NewNode(
2861       machine()->WordEqual(),
2862       graph()->NewNode(machine()->WordAnd(), value,
2863                        jsgraph()->IntPtrConstant(kSmiTagMask)),
2864       jsgraph()->IntPtrConstant(kSmiTag));
2865 }
2866 
SmiMaxValueConstant()2867 Node* EffectControlLinearizer::SmiMaxValueConstant() {
2868   return jsgraph()->Int32Constant(Smi::kMaxValue);
2869 }
2870 
SmiShiftBitsConstant()2871 Node* EffectControlLinearizer::SmiShiftBitsConstant() {
2872   return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize);
2873 }
2874 
2875 EffectControlLinearizer::ValueEffectControl
LowerPlainPrimitiveToNumber(Node * node,Node * effect,Node * control)2876 EffectControlLinearizer::LowerPlainPrimitiveToNumber(Node* node, Node* effect,
2877                                                      Node* control) {
2878   Node* value = node->InputAt(0);
2879   Node* result = effect =
2880       graph()->NewNode(ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(),
2881                        value, jsgraph()->NoContextConstant(), effect);
2882   return ValueEffectControl(result, effect, control);
2883 }
2884 
2885 EffectControlLinearizer::ValueEffectControl
LowerPlainPrimitiveToWord32(Node * node,Node * effect,Node * control)2886 EffectControlLinearizer::LowerPlainPrimitiveToWord32(Node* node, Node* effect,
2887                                                      Node* control) {
2888   Node* value = node->InputAt(0);
2889 
2890   Node* check0 = ObjectIsSmi(value);
2891   Node* branch0 =
2892       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
2893 
2894   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2895   Node* etrue0 = effect;
2896   Node* vtrue0 = ChangeSmiToInt32(value);
2897 
2898   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2899   Node* efalse0 = effect;
2900   Node* vfalse0;
2901   {
2902     vfalse0 = efalse0 = graph()->NewNode(
2903         ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value,
2904         jsgraph()->NoContextConstant(), efalse0);
2905 
2906     Node* check1 = ObjectIsSmi(vfalse0);
2907     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
2908 
2909     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2910     Node* etrue1 = efalse0;
2911     Node* vtrue1 = ChangeSmiToInt32(vfalse0);
2912 
2913     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2914     Node* efalse1 = efalse0;
2915     Node* vfalse1;
2916     {
2917       vfalse1 = efalse1 = graph()->NewNode(
2918           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
2919           efalse1, if_false1);
2920       vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1);
2921     }
2922 
2923     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2924     efalse0 =
2925         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
2926     vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2927                                vtrue1, vfalse1, if_false0);
2928   }
2929 
2930   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2931   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2932   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2933                            vtrue0, vfalse0, control);
2934   return ValueEffectControl(value, effect, control);
2935 }
2936 
2937 EffectControlLinearizer::ValueEffectControl
LowerPlainPrimitiveToFloat64(Node * node,Node * effect,Node * control)2938 EffectControlLinearizer::LowerPlainPrimitiveToFloat64(Node* node, Node* effect,
2939                                                       Node* control) {
2940   Node* value = node->InputAt(0);
2941 
2942   Node* check0 = ObjectIsSmi(value);
2943   Node* branch0 =
2944       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
2945 
2946   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2947   Node* etrue0 = effect;
2948   Node* vtrue0;
2949   {
2950     vtrue0 = ChangeSmiToInt32(value);
2951     vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
2952   }
2953 
2954   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2955   Node* efalse0 = effect;
2956   Node* vfalse0;
2957   {
2958     vfalse0 = efalse0 = graph()->NewNode(
2959         ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value,
2960         jsgraph()->NoContextConstant(), efalse0);
2961 
2962     Node* check1 = ObjectIsSmi(vfalse0);
2963     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
2964 
2965     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2966     Node* etrue1 = efalse0;
2967     Node* vtrue1;
2968     {
2969       vtrue1 = ChangeSmiToInt32(vfalse0);
2970       vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
2971     }
2972 
2973     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2974     Node* efalse1 = efalse0;
2975     Node* vfalse1;
2976     {
2977       vfalse1 = efalse1 = graph()->NewNode(
2978           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
2979           efalse1, if_false1);
2980     }
2981 
2982     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2983     efalse0 =
2984         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
2985     vfalse0 =
2986         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2987                          vtrue1, vfalse1, if_false0);
2988   }
2989 
2990   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2991   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2992   value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2993                            vtrue0, vfalse0, control);
2994   return ValueEffectControl(value, effect, control);
2995 }
2996 
2997 EffectControlLinearizer::ValueEffectControl
LowerEnsureWritableFastElements(Node * node,Node * effect,Node * control)2998 EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node,
2999                                                          Node* effect,
3000                                                          Node* control) {
3001   Node* object = node->InputAt(0);
3002   Node* elements = node->InputAt(1);
3003 
3004   // Load the current map of {elements}.
3005   Node* elements_map = effect =
3006       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
3007                        elements, effect, control);
3008 
3009   // Check if {elements} is not a copy-on-write FixedArray.
3010   Node* check = graph()->NewNode(machine()->WordEqual(), elements_map,
3011                                  jsgraph()->FixedArrayMapConstant());
3012   Node* branch =
3013       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
3014 
3015   // Nothing to do if the {elements} are not copy-on-write.
3016   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
3017   Node* etrue = effect;
3018   Node* vtrue = elements;
3019 
3020   // We need to take a copy of the {elements} and set them up for {object}.
3021   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
3022   Node* efalse = effect;
3023   Node* vfalse;
3024   {
3025     // We need to create a copy of the {elements} for {object}.
3026     Operator::Properties properties = Operator::kEliminatable;
3027     Callable callable = CodeFactory::CopyFastSmiOrObjectElements(isolate());
3028     CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
3029     CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
3030         isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3031         properties);
3032     vfalse = efalse = graph()->NewNode(
3033         common()->Call(desc), jsgraph()->HeapConstant(callable.code()), object,
3034         jsgraph()->NoContextConstant(), efalse);
3035   }
3036 
3037   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
3038   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
3039   Node* value = graph()->NewNode(
3040       common()->Phi(MachineRepresentation::kTagged, 2), vtrue, vfalse, control);
3041 
3042   return ValueEffectControl(value, effect, control);
3043 }
3044 
3045 EffectControlLinearizer::ValueEffectControl
LowerMaybeGrowFastElements(Node * node,Node * frame_state,Node * effect,Node * control)3046 EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node,
3047                                                     Node* frame_state,
3048                                                     Node* effect,
3049                                                     Node* control) {
3050   GrowFastElementsFlags flags = GrowFastElementsFlagsOf(node->op());
3051   Node* object = node->InputAt(0);
3052   Node* elements = node->InputAt(1);
3053   Node* index = node->InputAt(2);
3054   Node* length = node->InputAt(3);
3055 
3056   Node* check0 = graph()->NewNode((flags & GrowFastElementsFlag::kHoleyElements)
3057                                       ? machine()->Uint32LessThanOrEqual()
3058                                       : machine()->Word32Equal(),
3059                                   length, index);
3060   Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
3061 
3062   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3063   Node* etrue0 = effect;
3064   Node* vtrue0 = elements;
3065   {
3066     // Load the length of the {elements} backing store.
3067     Node* elements_length = etrue0 = graph()->NewNode(
3068         simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), elements,
3069         etrue0, if_true0);
3070     elements_length = ChangeSmiToInt32(elements_length);
3071 
3072     // Check if we need to grow the {elements} backing store.
3073     Node* check1 =
3074         graph()->NewNode(machine()->Uint32LessThan(), index, elements_length);
3075     Node* branch1 =
3076         graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0);
3077 
3078     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3079     Node* etrue1 = etrue0;
3080     Node* vtrue1 = vtrue0;
3081 
3082     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3083     Node* efalse1 = etrue0;
3084     Node* vfalse1 = vtrue0;
3085     {
3086       // We need to grow the {elements} for {object}.
3087       Operator::Properties properties = Operator::kEliminatable;
3088       Callable callable =
3089           (flags & GrowFastElementsFlag::kDoubleElements)
3090               ? CodeFactory::GrowFastDoubleElements(isolate())
3091               : CodeFactory::GrowFastSmiOrObjectElements(isolate());
3092       CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
3093       CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
3094           isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3095           properties);
3096       vfalse1 = efalse1 = graph()->NewNode(
3097           common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
3098           object, ChangeInt32ToSmi(index), jsgraph()->NoContextConstant(),
3099           efalse1);
3100 
3101       // Ensure that we were able to grow the {elements}.
3102       // TODO(turbofan): We use kSmi as reason here similar to Crankshaft,
3103       // but maybe we should just introduce a reason that makes sense.
3104       efalse1 = if_false1 = graph()->NewNode(
3105           common()->DeoptimizeIf(DeoptimizeReason::kSmi), ObjectIsSmi(vfalse1),
3106           frame_state, efalse1, if_false1);
3107     }
3108 
3109     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3110     etrue0 =
3111         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
3112     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
3113                               vtrue1, vfalse1, if_true0);
3114 
3115     // For JSArray {object}s we also need to update the "length".
3116     if (flags & GrowFastElementsFlag::kArrayObject) {
3117       // Compute the new {length}.
3118       Node* object_length = ChangeInt32ToSmi(graph()->NewNode(
3119           machine()->Int32Add(), index, jsgraph()->Int32Constant(1)));
3120 
3121       // Update the "length" property of the {object}.
3122       etrue0 =
3123           graph()->NewNode(simplified()->StoreField(
3124                                AccessBuilder::ForJSArrayLength(FAST_ELEMENTS)),
3125                            object, object_length, etrue0, if_true0);
3126     }
3127   }
3128 
3129   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3130   Node* efalse0 = effect;
3131   Node* vfalse0 = elements;
3132   {
3133     // In case of non-holey {elements}, we need to verify that the {index} is
3134     // in-bounds, otherwise for holey {elements}, the check above already
3135     // guards the index (and the operator forces {index} to be unsigned).
3136     if (!(flags & GrowFastElementsFlag::kHoleyElements)) {
3137       Node* check1 =
3138           graph()->NewNode(machine()->Uint32LessThan(), index, length);
3139       efalse0 = if_false0 = graph()->NewNode(
3140           common()->DeoptimizeUnless(DeoptimizeReason::kOutOfBounds), check1,
3141           frame_state, efalse0, if_false0);
3142     }
3143   }
3144 
3145   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3146   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
3147   Node* value =
3148       graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), vtrue0,
3149                        vfalse0, control);
3150 
3151   return ValueEffectControl(value, effect, control);
3152 }
3153 
3154 EffectControlLinearizer::ValueEffectControl
LowerTransitionElementsKind(Node * node,Node * effect,Node * control)3155 EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect,
3156                                                      Node* control) {
3157   ElementsTransition const transition = ElementsTransitionOf(node->op());
3158   Node* object = node->InputAt(0);
3159   Node* source_map = node->InputAt(1);
3160   Node* target_map = node->InputAt(2);
3161 
3162   // Load the current map of {object}.
3163   Node* object_map = effect =
3164       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object,
3165                        effect, control);
3166 
3167   // Check if {object_map} is the same as {source_map}.
3168   Node* check =
3169       graph()->NewNode(machine()->WordEqual(), object_map, source_map);
3170   Node* branch =
3171       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
3172 
3173   // Migrate the {object} from {source_map} to {target_map}.
3174   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
3175   Node* etrue = effect;
3176   {
3177     switch (transition) {
3178       case ElementsTransition::kFastTransition: {
3179         // In-place migration of {object}, just store the {target_map}.
3180         etrue =
3181             graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
3182                              object, target_map, etrue, if_true);
3183         break;
3184       }
3185       case ElementsTransition::kSlowTransition: {
3186         // Instance migration, call out to the runtime for {object}.
3187         Operator::Properties properties =
3188             Operator::kNoDeopt | Operator::kNoThrow;
3189         Runtime::FunctionId id = Runtime::kTransitionElementsKind;
3190         CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
3191             graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
3192         etrue = graph()->NewNode(
3193             common()->Call(desc), jsgraph()->CEntryStubConstant(1), object,
3194             target_map,
3195             jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
3196             jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(), etrue,
3197             if_true);
3198         break;
3199       }
3200     }
3201   }
3202 
3203   // Nothing to do if the {object} doesn't have the {source_map}.
3204   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
3205   Node* efalse = effect;
3206 
3207   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
3208   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
3209 
3210   return ValueEffectControl(nullptr, effect, control);
3211 }
3212 
3213 EffectControlLinearizer::ValueEffectControl
LowerLoadTypedElement(Node * node,Node * effect,Node * control)3214 EffectControlLinearizer::LowerLoadTypedElement(Node* node, Node* effect,
3215                                                Node* control) {
3216   ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
3217   Node* buffer = node->InputAt(0);
3218   Node* base = node->InputAt(1);
3219   Node* external = node->InputAt(2);
3220   Node* index = node->InputAt(3);
3221 
3222   // We need to keep the {buffer} alive so that the GC will not release the
3223   // ArrayBuffer (if there's any) as long as we are still operating on it.
3224   effect = graph()->NewNode(common()->Retain(), buffer, effect);
3225 
3226   // Compute the effective storage pointer.
3227   Node* storage = effect = graph()->NewNode(machine()->UnsafePointerAdd(), base,
3228                                             external, effect, control);
3229 
3230   // Perform the actual typed element access.
3231   Node* value = effect = graph()->NewNode(
3232       simplified()->LoadElement(
3233           AccessBuilder::ForTypedArrayElement(array_type, true)),
3234       storage, index, effect, control);
3235 
3236   return ValueEffectControl(value, effect, control);
3237 }
3238 
3239 EffectControlLinearizer::ValueEffectControl
LowerStoreTypedElement(Node * node,Node * effect,Node * control)3240 EffectControlLinearizer::LowerStoreTypedElement(Node* node, Node* effect,
3241                                                 Node* control) {
3242   ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
3243   Node* buffer = node->InputAt(0);
3244   Node* base = node->InputAt(1);
3245   Node* external = node->InputAt(2);
3246   Node* index = node->InputAt(3);
3247   Node* value = node->InputAt(4);
3248 
3249   // We need to keep the {buffer} alive so that the GC will not release the
3250   // ArrayBuffer (if there's any) as long as we are still operating on it.
3251   effect = graph()->NewNode(common()->Retain(), buffer, effect);
3252 
3253   // Compute the effective storage pointer.
3254   Node* storage = effect = graph()->NewNode(machine()->UnsafePointerAdd(), base,
3255                                             external, effect, control);
3256 
3257   // Perform the actual typed element access.
3258   effect = graph()->NewNode(
3259       simplified()->StoreElement(
3260           AccessBuilder::ForTypedArrayElement(array_type, true)),
3261       storage, index, value, effect, control);
3262 
3263   return ValueEffectControl(nullptr, effect, control);
3264 }
3265 
3266 EffectControlLinearizer::ValueEffectControl
LowerFloat64RoundUp(Node * node,Node * effect,Node * control)3267 EffectControlLinearizer::LowerFloat64RoundUp(Node* node, Node* effect,
3268                                              Node* control) {
3269   // Nothing to be done if a fast hardware instruction is available.
3270   if (machine()->Float64RoundUp().IsSupported()) {
3271     return ValueEffectControl(node, effect, control);
3272   }
3273 
3274   Node* const one = jsgraph()->Float64Constant(1.0);
3275   Node* const zero = jsgraph()->Float64Constant(0.0);
3276   Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
3277   Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
3278   Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
3279   Node* const input = node->InputAt(0);
3280 
3281   // General case for ceil.
3282   //
3283   //   if 0.0 < input then
3284   //     if 2^52 <= input then
3285   //       input
3286   //     else
3287   //       let temp1 = (2^52 + input) - 2^52 in
3288   //       if temp1 < input then
3289   //         temp1 + 1
3290   //       else
3291   //         temp1
3292   //   else
3293   //     if input == 0 then
3294   //       input
3295   //     else
3296   //       if input <= -2^52 then
3297   //         input
3298   //       else
3299   //         let temp1 = -0 - input in
3300   //         let temp2 = (2^52 + temp1) - 2^52 in
3301   //         let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
3302   //         -0 - temp3
3303   //
3304   // Note: We do not use the Diamond helper class here, because it really hurts
3305   // readability with nested diamonds.
3306 
3307   Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
3308   Node* branch0 =
3309       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
3310 
3311   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3312   Node* vtrue0;
3313   {
3314     Node* check1 =
3315         graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
3316     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
3317 
3318     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3319     Node* vtrue1 = input;
3320 
3321     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3322     Node* vfalse1;
3323     {
3324       Node* temp1 = graph()->NewNode(
3325           machine()->Float64Sub(),
3326           graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
3327       vfalse1 = graph()->NewNode(
3328           common()->Select(MachineRepresentation::kFloat64),
3329           graph()->NewNode(machine()->Float64LessThan(), temp1, input),
3330           graph()->NewNode(machine()->Float64Add(), temp1, one), temp1);
3331     }
3332 
3333     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3334     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3335                               vtrue1, vfalse1, if_true0);
3336   }
3337 
3338   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3339   Node* vfalse0;
3340   {
3341     Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
3342     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3343                                      check1, if_false0);
3344 
3345     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3346     Node* vtrue1 = input;
3347 
3348     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3349     Node* vfalse1;
3350     {
3351       Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
3352                                       input, minus_two_52);
3353       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3354                                        check2, if_false1);
3355 
3356       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
3357       Node* vtrue2 = input;
3358 
3359       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
3360       Node* vfalse2;
3361       {
3362         Node* temp1 =
3363             graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
3364         Node* temp2 = graph()->NewNode(
3365             machine()->Float64Sub(),
3366             graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
3367         Node* temp3 = graph()->NewNode(
3368             common()->Select(MachineRepresentation::kFloat64),
3369             graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
3370             graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
3371         vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
3372       }
3373 
3374       if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
3375       vfalse1 =
3376           graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3377                            vtrue2, vfalse2, if_false1);
3378     }
3379 
3380     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3381     vfalse0 =
3382         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3383                          vtrue1, vfalse1, if_false0);
3384   }
3385 
3386   Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3387   Node* value =
3388       graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3389                        vtrue0, vfalse0, merge0);
3390   return ValueEffectControl(value, effect, merge0);
3391 }
3392 
3393 EffectControlLinearizer::ValueEffectControl
BuildFloat64RoundDown(Node * value,Node * effect,Node * control)3394 EffectControlLinearizer::BuildFloat64RoundDown(Node* value, Node* effect,
3395                                                Node* control) {
3396   if (machine()->Float64RoundDown().IsSupported()) {
3397     value = graph()->NewNode(machine()->Float64RoundDown().op(), value);
3398   } else {
3399     Node* const one = jsgraph()->Float64Constant(1.0);
3400     Node* const zero = jsgraph()->Float64Constant(0.0);
3401     Node* const minus_one = jsgraph()->Float64Constant(-1.0);
3402     Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
3403     Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
3404     Node* const minus_two_52 =
3405         jsgraph()->Float64Constant(-4503599627370496.0E0);
3406     Node* const input = value;
3407 
3408     // General case for floor.
3409     //
3410     //   if 0.0 < input then
3411     //     if 2^52 <= input then
3412     //       input
3413     //     else
3414     //       let temp1 = (2^52 + input) - 2^52 in
3415     //       if input < temp1 then
3416     //         temp1 - 1
3417     //       else
3418     //         temp1
3419     //   else
3420     //     if input == 0 then
3421     //       input
3422     //     else
3423     //       if input <= -2^52 then
3424     //         input
3425     //       else
3426     //         let temp1 = -0 - input in
3427     //         let temp2 = (2^52 + temp1) - 2^52 in
3428     //         if temp2 < temp1 then
3429     //           -1 - temp2
3430     //         else
3431     //           -0 - temp2
3432     //
3433     // Note: We do not use the Diamond helper class here, because it really
3434     // hurts
3435     // readability with nested diamonds.
3436 
3437     Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
3438     Node* branch0 =
3439         graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
3440 
3441     Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3442     Node* vtrue0;
3443     {
3444       Node* check1 =
3445           graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
3446       Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
3447 
3448       Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3449       Node* vtrue1 = input;
3450 
3451       Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3452       Node* vfalse1;
3453       {
3454         Node* temp1 = graph()->NewNode(
3455             machine()->Float64Sub(),
3456             graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
3457         vfalse1 = graph()->NewNode(
3458             common()->Select(MachineRepresentation::kFloat64),
3459             graph()->NewNode(machine()->Float64LessThan(), input, temp1),
3460             graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
3461       }
3462 
3463       if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3464       vtrue0 =
3465           graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3466                            vtrue1, vfalse1, if_true0);
3467     }
3468 
3469     Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3470     Node* vfalse0;
3471     {
3472       Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
3473       Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3474                                        check1, if_false0);
3475 
3476       Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3477       Node* vtrue1 = input;
3478 
3479       Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3480       Node* vfalse1;
3481       {
3482         Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
3483                                         input, minus_two_52);
3484         Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3485                                          check2, if_false1);
3486 
3487         Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
3488         Node* vtrue2 = input;
3489 
3490         Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
3491         Node* vfalse2;
3492         {
3493           Node* temp1 =
3494               graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
3495           Node* temp2 = graph()->NewNode(
3496               machine()->Float64Sub(),
3497               graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
3498           vfalse2 = graph()->NewNode(
3499               common()->Select(MachineRepresentation::kFloat64),
3500               graph()->NewNode(machine()->Float64LessThan(), temp2, temp1),
3501               graph()->NewNode(machine()->Float64Sub(), minus_one, temp2),
3502               graph()->NewNode(machine()->Float64Sub(), minus_zero, temp2));
3503         }
3504 
3505         if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
3506         vfalse1 =
3507             graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3508                              vtrue2, vfalse2, if_false1);
3509       }
3510 
3511       if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3512       vfalse0 =
3513           graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3514                            vtrue1, vfalse1, if_false0);
3515     }
3516 
3517     control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3518     value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3519                              vtrue0, vfalse0, control);
3520   }
3521   return ValueEffectControl(value, effect, control);
3522 }
3523 
3524 EffectControlLinearizer::ValueEffectControl
LowerFloat64RoundDown(Node * node,Node * effect,Node * control)3525 EffectControlLinearizer::LowerFloat64RoundDown(Node* node, Node* effect,
3526                                                Node* control) {
3527   // Nothing to be done if a fast hardware instruction is available.
3528   if (machine()->Float64RoundDown().IsSupported()) {
3529     return ValueEffectControl(node, effect, control);
3530   }
3531 
3532   Node* const input = node->InputAt(0);
3533   return BuildFloat64RoundDown(input, effect, control);
3534 }
3535 
3536 EffectControlLinearizer::ValueEffectControl
LowerFloat64RoundTiesEven(Node * node,Node * effect,Node * control)3537 EffectControlLinearizer::LowerFloat64RoundTiesEven(Node* node, Node* effect,
3538                                                    Node* control) {
3539   // Nothing to be done if a fast hardware instruction is available.
3540   if (machine()->Float64RoundTiesEven().IsSupported()) {
3541     return ValueEffectControl(node, effect, control);
3542   }
3543 
3544   Node* const one = jsgraph()->Float64Constant(1.0);
3545   Node* const two = jsgraph()->Float64Constant(2.0);
3546   Node* const half = jsgraph()->Float64Constant(0.5);
3547   Node* const zero = jsgraph()->Float64Constant(0.0);
3548   Node* const input = node->InputAt(0);
3549 
3550   // Generate case for round ties to even:
3551   //
3552   //   let value = floor(input) in
3553   //   let temp1 = input - value in
3554   //   if temp1 < 0.5 then
3555   //     value
3556   //   else if 0.5 < temp1 then
3557   //     value + 1.0
3558   //   else
3559   //     let temp2 = value % 2.0 in
3560   //     if temp2 == 0.0 then
3561   //       value
3562   //     else
3563   //       value + 1.0
3564   //
3565   // Note: We do not use the Diamond helper class here, because it really hurts
3566   // readability with nested diamonds.
3567 
3568   ValueEffectControl continuation =
3569       BuildFloat64RoundDown(input, effect, control);
3570   Node* value = continuation.value;
3571   effect = continuation.effect;
3572   control = continuation.control;
3573 
3574   Node* temp1 = graph()->NewNode(machine()->Float64Sub(), input, value);
3575 
3576   Node* check0 = graph()->NewNode(machine()->Float64LessThan(), temp1, half);
3577   Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
3578 
3579   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3580   Node* vtrue0 = value;
3581 
3582   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3583   Node* vfalse0;
3584   {
3585     Node* check1 = graph()->NewNode(machine()->Float64LessThan(), half, temp1);
3586     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
3587 
3588     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3589     Node* vtrue1 = graph()->NewNode(machine()->Float64Add(), value, one);
3590 
3591     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3592     Node* vfalse1;
3593     {
3594       Node* temp2 = graph()->NewNode(machine()->Float64Mod(), value, two);
3595 
3596       Node* check2 = graph()->NewNode(machine()->Float64Equal(), temp2, zero);
3597       Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
3598 
3599       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
3600       Node* vtrue2 = value;
3601 
3602       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
3603       Node* vfalse2 = graph()->NewNode(machine()->Float64Add(), value, one);
3604 
3605       if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
3606       vfalse1 =
3607           graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3608                            vtrue2, vfalse2, if_false1);
3609     }
3610 
3611     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3612     vfalse0 =
3613         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3614                          vtrue1, vfalse1, if_false0);
3615   }
3616 
3617   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3618   value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3619                            vtrue0, vfalse0, control);
3620 
3621   return ValueEffectControl(value, effect, control);
3622 }
3623 
3624 EffectControlLinearizer::ValueEffectControl
LowerFloat64RoundTruncate(Node * node,Node * effect,Node * control)3625 EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node, Node* effect,
3626                                                    Node* control) {
3627   // Nothing to be done if a fast hardware instruction is available.
3628   if (machine()->Float64RoundTruncate().IsSupported()) {
3629     return ValueEffectControl(node, effect, control);
3630   }
3631 
3632   Node* const one = jsgraph()->Float64Constant(1.0);
3633   Node* const zero = jsgraph()->Float64Constant(0.0);
3634   Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
3635   Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
3636   Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
3637   Node* const input = node->InputAt(0);
3638 
3639   // General case for trunc.
3640   //
3641   //   if 0.0 < input then
3642   //     if 2^52 <= input then
3643   //       input
3644   //     else
3645   //       let temp1 = (2^52 + input) - 2^52 in
3646   //       if input < temp1 then
3647   //         temp1 - 1
3648   //       else
3649   //         temp1
3650   //   else
3651   //     if input == 0 then
3652   //       input
3653   //     else
3654   //       if input <= -2^52 then
3655   //         input
3656   //       else
3657   //         let temp1 = -0 - input in
3658   //         let temp2 = (2^52 + temp1) - 2^52 in
3659   //         let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
3660   //         -0 - temp3
3661   //
3662   // Note: We do not use the Diamond helper class here, because it really hurts
3663   // readability with nested diamonds.
3664 
3665   Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
3666   Node* branch0 =
3667       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
3668 
3669   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3670   Node* vtrue0;
3671   {
3672     Node* check1 =
3673         graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
3674     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
3675 
3676     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3677     Node* vtrue1 = input;
3678 
3679     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3680     Node* vfalse1;
3681     {
3682       Node* temp1 = graph()->NewNode(
3683           machine()->Float64Sub(),
3684           graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
3685       vfalse1 = graph()->NewNode(
3686           common()->Select(MachineRepresentation::kFloat64),
3687           graph()->NewNode(machine()->Float64LessThan(), input, temp1),
3688           graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
3689     }
3690 
3691     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3692     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3693                               vtrue1, vfalse1, if_true0);
3694   }
3695 
3696   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3697   Node* vfalse0;
3698   {
3699     Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
3700     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3701                                      check1, if_false0);
3702 
3703     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3704     Node* vtrue1 = input;
3705 
3706     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3707     Node* vfalse1;
3708     {
3709       Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
3710                                       input, minus_two_52);
3711       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3712                                        check2, if_false1);
3713 
3714       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
3715       Node* vtrue2 = input;
3716 
3717       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
3718       Node* vfalse2;
3719       {
3720         Node* temp1 =
3721             graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
3722         Node* temp2 = graph()->NewNode(
3723             machine()->Float64Sub(),
3724             graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
3725         Node* temp3 = graph()->NewNode(
3726             common()->Select(MachineRepresentation::kFloat64),
3727             graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
3728             graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
3729         vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
3730       }
3731 
3732       if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
3733       vfalse1 =
3734           graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3735                            vtrue2, vfalse2, if_false1);
3736     }
3737 
3738     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3739     vfalse0 =
3740         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3741                          vtrue1, vfalse1, if_false0);
3742   }
3743 
3744   Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3745   Node* value =
3746       graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3747                        vtrue0, vfalse0, merge0);
3748   return ValueEffectControl(value, effect, merge0);
3749 }
3750 
factory() const3751 Factory* EffectControlLinearizer::factory() const {
3752   return isolate()->factory();
3753 }
3754 
isolate() const3755 Isolate* EffectControlLinearizer::isolate() const {
3756   return jsgraph()->isolate();
3757 }
3758 
ToNumberOperator()3759 Operator const* EffectControlLinearizer::ToNumberOperator() {
3760   if (!to_number_operator_.is_set()) {
3761     Callable callable = CodeFactory::ToNumber(isolate());
3762     CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
3763     CallDescriptor* desc = Linkage::GetStubCallDescriptor(
3764         isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3765         Operator::kEliminatable);
3766     to_number_operator_.set(common()->Call(desc));
3767   }
3768   return to_number_operator_.get();
3769 }
3770 
3771 }  // namespace compiler
3772 }  // namespace internal
3773 }  // namespace v8
3774