• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/compiler/backend/instruction-selector.h"
6 
7 #include <limits>
8 
9 #include "src/base/iterator.h"
10 #include "src/base/platform/wrappers.h"
11 #include "src/codegen/assembler-inl.h"
12 #include "src/codegen/interface-descriptors-inl.h"
13 #include "src/codegen/tick-counter.h"
14 #include "src/common/globals.h"
15 #include "src/compiler/backend/instruction-selector-impl.h"
16 #include "src/compiler/compiler-source-position-table.h"
17 #include "src/compiler/js-heap-broker.h"
18 #include "src/compiler/node-matchers.h"
19 #include "src/compiler/node-properties.h"
20 #include "src/compiler/pipeline.h"
21 #include "src/compiler/schedule.h"
22 #include "src/compiler/state-values-utils.h"
23 #include "src/deoptimizer/deoptimizer.h"
24 
25 #if V8_ENABLE_WEBASSEMBLY
26 #include "src/wasm/simd-shuffle.h"
27 #endif  // V8_ENABLE_WEBASSEMBLY
28 
29 namespace v8 {
30 namespace internal {
31 namespace compiler {
32 
NumberConstantToSmi(Node * node)33 Smi NumberConstantToSmi(Node* node) {
34   DCHECK_EQ(node->opcode(), IrOpcode::kNumberConstant);
35   const double d = OpParameter<double>(node->op());
36   Smi smi = Smi::FromInt(static_cast<int32_t>(d));
37   CHECK_EQ(smi.value(), d);
38   return smi;
39 }
40 
InstructionSelector(Zone * zone,size_t node_count,Linkage * linkage,InstructionSequence * sequence,Schedule * schedule,SourcePositionTable * source_positions,Frame * frame,EnableSwitchJumpTable enable_switch_jump_table,TickCounter * tick_counter,JSHeapBroker * broker,size_t * max_unoptimized_frame_height,size_t * max_pushed_argument_count,SourcePositionMode source_position_mode,Features features,EnableScheduling enable_scheduling,EnableRootsRelativeAddressing enable_roots_relative_addressing,EnableTraceTurboJson trace_turbo)41 InstructionSelector::InstructionSelector(
42     Zone* zone, size_t node_count, Linkage* linkage,
43     InstructionSequence* sequence, Schedule* schedule,
44     SourcePositionTable* source_positions, Frame* frame,
45     EnableSwitchJumpTable enable_switch_jump_table, TickCounter* tick_counter,
46     JSHeapBroker* broker, size_t* max_unoptimized_frame_height,
47     size_t* max_pushed_argument_count, SourcePositionMode source_position_mode,
48     Features features, EnableScheduling enable_scheduling,
49     EnableRootsRelativeAddressing enable_roots_relative_addressing,
50     EnableTraceTurboJson trace_turbo)
51     : zone_(zone),
52       linkage_(linkage),
53       sequence_(sequence),
54       source_positions_(source_positions),
55       source_position_mode_(source_position_mode),
56       features_(features),
57       schedule_(schedule),
58       current_block_(nullptr),
59       instructions_(zone),
60       continuation_inputs_(sequence->zone()),
61       continuation_outputs_(sequence->zone()),
62       continuation_temps_(sequence->zone()),
63       defined_(node_count, false, zone),
64       used_(node_count, false, zone),
65       effect_level_(node_count, 0, zone),
66       virtual_registers_(node_count,
67                          InstructionOperand::kInvalidVirtualRegister, zone),
68       virtual_register_rename_(zone),
69       scheduler_(nullptr),
70       enable_scheduling_(enable_scheduling),
71       enable_roots_relative_addressing_(enable_roots_relative_addressing),
72       enable_switch_jump_table_(enable_switch_jump_table),
73       state_values_cache_(zone),
74       frame_(frame),
75       instruction_selection_failed_(false),
76       instr_origins_(sequence->zone()),
77       trace_turbo_(trace_turbo),
78       tick_counter_(tick_counter),
79       broker_(broker),
80       max_unoptimized_frame_height_(max_unoptimized_frame_height),
81       max_pushed_argument_count_(max_pushed_argument_count)
82 #if V8_TARGET_ARCH_64_BIT
83       ,
84       phi_states_(node_count, Upper32BitsState::kNotYetChecked, zone)
85 #endif
86 {
87   DCHECK_EQ(*max_unoptimized_frame_height, 0);  // Caller-initialized.
88 
89   instructions_.reserve(node_count);
90   continuation_inputs_.reserve(5);
91   continuation_outputs_.reserve(2);
92 
93   if (trace_turbo_ == kEnableTraceTurboJson) {
94     instr_origins_.assign(node_count, {-1, 0});
95   }
96 }
97 
SelectInstructions()98 bool InstructionSelector::SelectInstructions() {
99   // Mark the inputs of all phis in loop headers as used.
100   BasicBlockVector* blocks = schedule()->rpo_order();
101   for (auto const block : *blocks) {
102     if (!block->IsLoopHeader()) continue;
103     DCHECK_LE(2u, block->PredecessorCount());
104     for (Node* const phi : *block) {
105       if (phi->opcode() != IrOpcode::kPhi) continue;
106 
107       // Mark all inputs as used.
108       for (Node* const input : phi->inputs()) {
109         MarkAsUsed(input);
110       }
111     }
112   }
113 
114   // Visit each basic block in post order.
115   for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) {
116     VisitBlock(*i);
117     if (instruction_selection_failed()) return false;
118   }
119 
120   // Schedule the selected instructions.
121   if (UseInstructionScheduling()) {
122     scheduler_ = zone()->New<InstructionScheduler>(zone(), sequence());
123   }
124 
125   for (auto const block : *blocks) {
126     InstructionBlock* instruction_block =
127         sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
128     for (size_t i = 0; i < instruction_block->phis().size(); i++) {
129       UpdateRenamesInPhi(instruction_block->PhiAt(i));
130     }
131     size_t end = instruction_block->code_end();
132     size_t start = instruction_block->code_start();
133     DCHECK_LE(end, start);
134     StartBlock(RpoNumber::FromInt(block->rpo_number()));
135     if (end != start) {
136       while (start-- > end + 1) {
137         UpdateRenames(instructions_[start]);
138         AddInstruction(instructions_[start]);
139       }
140       UpdateRenames(instructions_[end]);
141       AddTerminator(instructions_[end]);
142     }
143     EndBlock(RpoNumber::FromInt(block->rpo_number()));
144   }
145 #if DEBUG
146   sequence()->ValidateSSA();
147 #endif
148   return true;
149 }
150 
StartBlock(RpoNumber rpo)151 void InstructionSelector::StartBlock(RpoNumber rpo) {
152   if (UseInstructionScheduling()) {
153     DCHECK_NOT_NULL(scheduler_);
154     scheduler_->StartBlock(rpo);
155   } else {
156     sequence()->StartBlock(rpo);
157   }
158 }
159 
EndBlock(RpoNumber rpo)160 void InstructionSelector::EndBlock(RpoNumber rpo) {
161   if (UseInstructionScheduling()) {
162     DCHECK_NOT_NULL(scheduler_);
163     scheduler_->EndBlock(rpo);
164   } else {
165     sequence()->EndBlock(rpo);
166   }
167 }
168 
AddTerminator(Instruction * instr)169 void InstructionSelector::AddTerminator(Instruction* instr) {
170   if (UseInstructionScheduling()) {
171     DCHECK_NOT_NULL(scheduler_);
172     scheduler_->AddTerminator(instr);
173   } else {
174     sequence()->AddInstruction(instr);
175   }
176 }
177 
AddInstruction(Instruction * instr)178 void InstructionSelector::AddInstruction(Instruction* instr) {
179   if (UseInstructionScheduling()) {
180     DCHECK_NOT_NULL(scheduler_);
181     scheduler_->AddInstruction(instr);
182   } else {
183     sequence()->AddInstruction(instr);
184   }
185 }
186 
Emit(InstructionCode opcode,InstructionOperand output,size_t temp_count,InstructionOperand * temps)187 Instruction* InstructionSelector::Emit(InstructionCode opcode,
188                                        InstructionOperand output,
189                                        size_t temp_count,
190                                        InstructionOperand* temps) {
191   size_t output_count = output.IsInvalid() ? 0 : 1;
192   return Emit(opcode, output_count, &output, 0, nullptr, temp_count, temps);
193 }
194 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,size_t temp_count,InstructionOperand * temps)195 Instruction* InstructionSelector::Emit(InstructionCode opcode,
196                                        InstructionOperand output,
197                                        InstructionOperand a, size_t temp_count,
198                                        InstructionOperand* temps) {
199   size_t output_count = output.IsInvalid() ? 0 : 1;
200   return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
201 }
202 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,InstructionOperand b,size_t temp_count,InstructionOperand * temps)203 Instruction* InstructionSelector::Emit(InstructionCode opcode,
204                                        InstructionOperand output,
205                                        InstructionOperand a,
206                                        InstructionOperand b, size_t temp_count,
207                                        InstructionOperand* temps) {
208   size_t output_count = output.IsInvalid() ? 0 : 1;
209   InstructionOperand inputs[] = {a, b};
210   size_t input_count = arraysize(inputs);
211   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
212               temps);
213 }
214 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,InstructionOperand b,InstructionOperand c,size_t temp_count,InstructionOperand * temps)215 Instruction* InstructionSelector::Emit(InstructionCode opcode,
216                                        InstructionOperand output,
217                                        InstructionOperand a,
218                                        InstructionOperand b,
219                                        InstructionOperand c, size_t temp_count,
220                                        InstructionOperand* temps) {
221   size_t output_count = output.IsInvalid() ? 0 : 1;
222   InstructionOperand inputs[] = {a, b, c};
223   size_t input_count = arraysize(inputs);
224   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
225               temps);
226 }
227 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,InstructionOperand b,InstructionOperand c,InstructionOperand d,size_t temp_count,InstructionOperand * temps)228 Instruction* InstructionSelector::Emit(
229     InstructionCode opcode, InstructionOperand output, InstructionOperand a,
230     InstructionOperand b, InstructionOperand c, InstructionOperand d,
231     size_t temp_count, InstructionOperand* temps) {
232   size_t output_count = output.IsInvalid() ? 0 : 1;
233   InstructionOperand inputs[] = {a, b, c, d};
234   size_t input_count = arraysize(inputs);
235   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
236               temps);
237 }
238 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,InstructionOperand b,InstructionOperand c,InstructionOperand d,InstructionOperand e,size_t temp_count,InstructionOperand * temps)239 Instruction* InstructionSelector::Emit(
240     InstructionCode opcode, InstructionOperand output, InstructionOperand a,
241     InstructionOperand b, InstructionOperand c, InstructionOperand d,
242     InstructionOperand e, size_t temp_count, InstructionOperand* temps) {
243   size_t output_count = output.IsInvalid() ? 0 : 1;
244   InstructionOperand inputs[] = {a, b, c, d, e};
245   size_t input_count = arraysize(inputs);
246   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
247               temps);
248 }
249 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,InstructionOperand b,InstructionOperand c,InstructionOperand d,InstructionOperand e,InstructionOperand f,size_t temp_count,InstructionOperand * temps)250 Instruction* InstructionSelector::Emit(
251     InstructionCode opcode, InstructionOperand output, InstructionOperand a,
252     InstructionOperand b, InstructionOperand c, InstructionOperand d,
253     InstructionOperand e, InstructionOperand f, size_t temp_count,
254     InstructionOperand* temps) {
255   size_t output_count = output.IsInvalid() ? 0 : 1;
256   InstructionOperand inputs[] = {a, b, c, d, e, f};
257   size_t input_count = arraysize(inputs);
258   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
259               temps);
260 }
261 
Emit(InstructionCode opcode,size_t output_count,InstructionOperand * outputs,size_t input_count,InstructionOperand * inputs,size_t temp_count,InstructionOperand * temps)262 Instruction* InstructionSelector::Emit(
263     InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
264     size_t input_count, InstructionOperand* inputs, size_t temp_count,
265     InstructionOperand* temps) {
266   if (output_count >= Instruction::kMaxOutputCount ||
267       input_count >= Instruction::kMaxInputCount ||
268       temp_count >= Instruction::kMaxTempCount) {
269     set_instruction_selection_failed();
270     return nullptr;
271   }
272 
273   Instruction* instr =
274       Instruction::New(instruction_zone(), opcode, output_count, outputs,
275                        input_count, inputs, temp_count, temps);
276   return Emit(instr);
277 }
278 
Emit(Instruction * instr)279 Instruction* InstructionSelector::Emit(Instruction* instr) {
280   instructions_.push_back(instr);
281   return instr;
282 }
283 
CanCover(Node * user,Node * node) const284 bool InstructionSelector::CanCover(Node* user, Node* node) const {
285   // 1. Both {user} and {node} must be in the same basic block.
286   if (schedule()->block(node) != current_block_) {
287     return false;
288   }
289   // 2. Pure {node}s must be owned by the {user}.
290   if (node->op()->HasProperty(Operator::kPure)) {
291     return node->OwnedBy(user);
292   }
293   // 3. Impure {node}s must match the effect level of {user}.
294   if (GetEffectLevel(node) != current_effect_level_) {
295     return false;
296   }
297   // 4. Only {node} must have value edges pointing to {user}.
298   for (Edge const edge : node->use_edges()) {
299     if (edge.from() != user && NodeProperties::IsValueEdge(edge)) {
300       return false;
301     }
302   }
303   return true;
304 }
305 
IsOnlyUserOfNodeInSameBlock(Node * user,Node * node) const306 bool InstructionSelector::IsOnlyUserOfNodeInSameBlock(Node* user,
307                                                       Node* node) const {
308   BasicBlock* bb_user = schedule()->block(user);
309   BasicBlock* bb_node = schedule()->block(node);
310   if (bb_user != bb_node) return false;
311   for (Edge const edge : node->use_edges()) {
312     Node* from = edge.from();
313     if ((from != user) && (schedule()->block(from) == bb_user)) {
314       return false;
315     }
316   }
317   return true;
318 }
319 
UpdateRenames(Instruction * instruction)320 void InstructionSelector::UpdateRenames(Instruction* instruction) {
321   for (size_t i = 0; i < instruction->InputCount(); i++) {
322     TryRename(instruction->InputAt(i));
323   }
324 }
325 
UpdateRenamesInPhi(PhiInstruction * phi)326 void InstructionSelector::UpdateRenamesInPhi(PhiInstruction* phi) {
327   for (size_t i = 0; i < phi->operands().size(); i++) {
328     int vreg = phi->operands()[i];
329     int renamed = GetRename(vreg);
330     if (vreg != renamed) {
331       phi->RenameInput(i, renamed);
332     }
333   }
334 }
335 
GetRename(int virtual_register)336 int InstructionSelector::GetRename(int virtual_register) {
337   int rename = virtual_register;
338   while (true) {
339     if (static_cast<size_t>(rename) >= virtual_register_rename_.size()) break;
340     int next = virtual_register_rename_[rename];
341     if (next == InstructionOperand::kInvalidVirtualRegister) {
342       break;
343     }
344     rename = next;
345   }
346   return rename;
347 }
348 
TryRename(InstructionOperand * op)349 void InstructionSelector::TryRename(InstructionOperand* op) {
350   if (!op->IsUnallocated()) return;
351   UnallocatedOperand* unalloc = UnallocatedOperand::cast(op);
352   int vreg = unalloc->virtual_register();
353   int rename = GetRename(vreg);
354   if (rename != vreg) {
355     *unalloc = UnallocatedOperand(*unalloc, rename);
356   }
357 }
358 
SetRename(const Node * node,const Node * rename)359 void InstructionSelector::SetRename(const Node* node, const Node* rename) {
360   int vreg = GetVirtualRegister(node);
361   if (static_cast<size_t>(vreg) >= virtual_register_rename_.size()) {
362     int invalid = InstructionOperand::kInvalidVirtualRegister;
363     virtual_register_rename_.resize(vreg + 1, invalid);
364   }
365   virtual_register_rename_[vreg] = GetVirtualRegister(rename);
366 }
367 
GetVirtualRegister(const Node * node)368 int InstructionSelector::GetVirtualRegister(const Node* node) {
369   DCHECK_NOT_NULL(node);
370   size_t const id = node->id();
371   DCHECK_LT(id, virtual_registers_.size());
372   int virtual_register = virtual_registers_[id];
373   if (virtual_register == InstructionOperand::kInvalidVirtualRegister) {
374     virtual_register = sequence()->NextVirtualRegister();
375     virtual_registers_[id] = virtual_register;
376   }
377   return virtual_register;
378 }
379 
GetVirtualRegistersForTesting() const380 const std::map<NodeId, int> InstructionSelector::GetVirtualRegistersForTesting()
381     const {
382   std::map<NodeId, int> virtual_registers;
383   for (size_t n = 0; n < virtual_registers_.size(); ++n) {
384     if (virtual_registers_[n] != InstructionOperand::kInvalidVirtualRegister) {
385       NodeId const id = static_cast<NodeId>(n);
386       virtual_registers.insert(std::make_pair(id, virtual_registers_[n]));
387     }
388   }
389   return virtual_registers;
390 }
391 
IsDefined(Node * node) const392 bool InstructionSelector::IsDefined(Node* node) const {
393   DCHECK_NOT_NULL(node);
394   size_t const id = node->id();
395   DCHECK_LT(id, defined_.size());
396   return defined_[id];
397 }
398 
MarkAsDefined(Node * node)399 void InstructionSelector::MarkAsDefined(Node* node) {
400   DCHECK_NOT_NULL(node);
401   size_t const id = node->id();
402   DCHECK_LT(id, defined_.size());
403   defined_[id] = true;
404 }
405 
IsUsed(Node * node) const406 bool InstructionSelector::IsUsed(Node* node) const {
407   DCHECK_NOT_NULL(node);
408   // TODO(bmeurer): This is a terrible monster hack, but we have to make sure
409   // that the Retain is actually emitted, otherwise the GC will mess up.
410   if (node->opcode() == IrOpcode::kRetain) return true;
411   if (!node->op()->HasProperty(Operator::kEliminatable)) return true;
412   size_t const id = node->id();
413   DCHECK_LT(id, used_.size());
414   return used_[id];
415 }
416 
MarkAsUsed(Node * node)417 void InstructionSelector::MarkAsUsed(Node* node) {
418   DCHECK_NOT_NULL(node);
419   size_t const id = node->id();
420   DCHECK_LT(id, used_.size());
421   used_[id] = true;
422 }
423 
GetEffectLevel(Node * node) const424 int InstructionSelector::GetEffectLevel(Node* node) const {
425   DCHECK_NOT_NULL(node);
426   size_t const id = node->id();
427   DCHECK_LT(id, effect_level_.size());
428   return effect_level_[id];
429 }
430 
GetEffectLevel(Node * node,FlagsContinuation * cont) const431 int InstructionSelector::GetEffectLevel(Node* node,
432                                         FlagsContinuation* cont) const {
433   return cont->IsBranch()
434              ? GetEffectLevel(
435                    cont->true_block()->PredecessorAt(0)->control_input())
436              : GetEffectLevel(node);
437 }
438 
SetEffectLevel(Node * node,int effect_level)439 void InstructionSelector::SetEffectLevel(Node* node, int effect_level) {
440   DCHECK_NOT_NULL(node);
441   size_t const id = node->id();
442   DCHECK_LT(id, effect_level_.size());
443   effect_level_[id] = effect_level;
444 }
445 
CanAddressRelativeToRootsRegister(const ExternalReference & reference) const446 bool InstructionSelector::CanAddressRelativeToRootsRegister(
447     const ExternalReference& reference) const {
448   // There are three things to consider here:
449   // 1. CanUseRootsRegister: Is kRootRegister initialized?
450   const bool root_register_is_available_and_initialized = CanUseRootsRegister();
451   if (!root_register_is_available_and_initialized) return false;
452 
453   // 2. enable_roots_relative_addressing_: Can we address everything on the heap
454   //    through the root register, i.e. are root-relative addresses to arbitrary
455   //    addresses guaranteed not to change between code generation and
456   //    execution?
457   const bool all_root_relative_offsets_are_constant =
458       (enable_roots_relative_addressing_ == kEnableRootsRelativeAddressing);
459   if (all_root_relative_offsets_are_constant) return true;
460 
461   // 3. IsAddressableThroughRootRegister: Is the target address guaranteed to
462   //    have a fixed root-relative offset? If so, we can ignore 2.
463   const bool this_root_relative_offset_is_constant =
464       TurboAssemblerBase::IsAddressableThroughRootRegister(isolate(),
465                                                            reference);
466   return this_root_relative_offset_is_constant;
467 }
468 
CanUseRootsRegister() const469 bool InstructionSelector::CanUseRootsRegister() const {
470   return linkage()->GetIncomingDescriptor()->flags() &
471          CallDescriptor::kCanUseRoots;
472 }
473 
MarkAsRepresentation(MachineRepresentation rep,const InstructionOperand & op)474 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
475                                                const InstructionOperand& op) {
476   UnallocatedOperand unalloc = UnallocatedOperand::cast(op);
477   sequence()->MarkAsRepresentation(rep, unalloc.virtual_register());
478 }
479 
MarkAsRepresentation(MachineRepresentation rep,Node * node)480 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
481                                                Node* node) {
482   sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node));
483 }
484 
485 namespace {
486 
OperandForDeopt(Isolate * isolate,OperandGenerator * g,Node * input,FrameStateInputKind kind,MachineRepresentation rep)487 InstructionOperand OperandForDeopt(Isolate* isolate, OperandGenerator* g,
488                                    Node* input, FrameStateInputKind kind,
489                                    MachineRepresentation rep) {
490   if (rep == MachineRepresentation::kNone) {
491     return g->TempImmediate(FrameStateDescriptor::kImpossibleValue);
492   }
493 
494   switch (input->opcode()) {
495     case IrOpcode::kInt32Constant:
496     case IrOpcode::kInt64Constant:
497     case IrOpcode::kFloat32Constant:
498     case IrOpcode::kFloat64Constant:
499     case IrOpcode::kDelayedStringConstant:
500       return g->UseImmediate(input);
501     case IrOpcode::kNumberConstant:
502       if (rep == MachineRepresentation::kWord32) {
503         Smi smi = NumberConstantToSmi(input);
504         return g->UseImmediate(static_cast<int32_t>(smi.ptr()));
505       } else {
506         return g->UseImmediate(input);
507       }
508     case IrOpcode::kCompressedHeapConstant:
509     case IrOpcode::kHeapConstant: {
510       if (!CanBeTaggedOrCompressedPointer(rep)) {
511         // If we have inconsistent static and dynamic types, e.g. if we
512         // smi-check a string, we can get here with a heap object that
513         // says it is a smi. In that case, we return an invalid instruction
514         // operand, which will be interpreted as an optimized-out value.
515 
516         // TODO(jarin) Ideally, we should turn the current instruction
517         // into an abort (we should never execute it).
518         return InstructionOperand();
519       }
520 
521       Handle<HeapObject> constant = HeapConstantOf(input->op());
522       RootIndex root_index;
523       if (isolate->roots_table().IsRootHandle(constant, &root_index) &&
524           root_index == RootIndex::kOptimizedOut) {
525         // For an optimized-out object we return an invalid instruction
526         // operand, so that we take the fast path for optimized-out values.
527         return InstructionOperand();
528       }
529 
530       return g->UseImmediate(input);
531     }
532     case IrOpcode::kArgumentsElementsState:
533     case IrOpcode::kArgumentsLengthState:
534     case IrOpcode::kObjectState:
535     case IrOpcode::kTypedObjectState:
536       UNREACHABLE();
537     default:
538       switch (kind) {
539         case FrameStateInputKind::kStackSlot:
540           return g->UseUniqueSlot(input);
541         case FrameStateInputKind::kAny:
542           // Currently deopts "wrap" other operations, so the deopt's inputs
543           // are potentially needed until the end of the deoptimising code.
544           return g->UseAnyAtEnd(input);
545       }
546   }
547   UNREACHABLE();
548 }
549 
550 }  // namespace
551 
552 class StateObjectDeduplicator {
553  public:
StateObjectDeduplicator(Zone * zone)554   explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {}
555   static const size_t kNotDuplicated = SIZE_MAX;
556 
GetObjectId(Node * node)557   size_t GetObjectId(Node* node) {
558     DCHECK(node->opcode() == IrOpcode::kTypedObjectState ||
559            node->opcode() == IrOpcode::kObjectId ||
560            node->opcode() == IrOpcode::kArgumentsElementsState);
561     for (size_t i = 0; i < objects_.size(); ++i) {
562       if (objects_[i] == node) return i;
563       // ObjectId nodes are the Turbofan way to express objects with the same
564       // identity in the deopt info. So they should always be mapped to
565       // previously appearing TypedObjectState nodes.
566       if (HasObjectId(objects_[i]) && HasObjectId(node) &&
567           ObjectIdOf(objects_[i]->op()) == ObjectIdOf(node->op())) {
568         return i;
569       }
570     }
571     DCHECK(node->opcode() == IrOpcode::kTypedObjectState ||
572            node->opcode() == IrOpcode::kArgumentsElementsState);
573     return kNotDuplicated;
574   }
575 
InsertObject(Node * node)576   size_t InsertObject(Node* node) {
577     DCHECK(node->opcode() == IrOpcode::kTypedObjectState ||
578            node->opcode() == IrOpcode::kObjectId ||
579            node->opcode() == IrOpcode::kArgumentsElementsState);
580     size_t id = objects_.size();
581     objects_.push_back(node);
582     return id;
583   }
584 
size() const585   size_t size() const { return objects_.size(); }
586 
587  private:
HasObjectId(Node * node)588   static bool HasObjectId(Node* node) {
589     return node->opcode() == IrOpcode::kTypedObjectState ||
590            node->opcode() == IrOpcode::kObjectId;
591   }
592 
593   ZoneVector<Node*> objects_;
594 };
595 
596 // Returns the number of instruction operands added to inputs.
AddOperandToStateValueDescriptor(StateValueList * values,InstructionOperandVector * inputs,OperandGenerator * g,StateObjectDeduplicator * deduplicator,Node * input,MachineType type,FrameStateInputKind kind,Zone * zone)597 size_t InstructionSelector::AddOperandToStateValueDescriptor(
598     StateValueList* values, InstructionOperandVector* inputs,
599     OperandGenerator* g, StateObjectDeduplicator* deduplicator, Node* input,
600     MachineType type, FrameStateInputKind kind, Zone* zone) {
601   DCHECK_NOT_NULL(input);
602   switch (input->opcode()) {
603     case IrOpcode::kArgumentsElementsState: {
604       values->PushArgumentsElements(ArgumentsStateTypeOf(input->op()));
605       // The elements backing store of an arguments object participates in the
606       // duplicate object counting, but can itself never appear duplicated.
607       DCHECK_EQ(StateObjectDeduplicator::kNotDuplicated,
608                 deduplicator->GetObjectId(input));
609       deduplicator->InsertObject(input);
610       return 0;
611     }
612     case IrOpcode::kArgumentsLengthState: {
613       values->PushArgumentsLength();
614       return 0;
615     }
616     case IrOpcode::kObjectState:
617       UNREACHABLE();
618     case IrOpcode::kTypedObjectState:
619     case IrOpcode::kObjectId: {
620       size_t id = deduplicator->GetObjectId(input);
621       if (id == StateObjectDeduplicator::kNotDuplicated) {
622         DCHECK_EQ(IrOpcode::kTypedObjectState, input->opcode());
623         size_t entries = 0;
624         id = deduplicator->InsertObject(input);
625         StateValueList* nested = values->PushRecursiveField(zone, id);
626         int const input_count = input->op()->ValueInputCount();
627         ZoneVector<MachineType> const* types = MachineTypesOf(input->op());
628         for (int i = 0; i < input_count; ++i) {
629           entries += AddOperandToStateValueDescriptor(
630               nested, inputs, g, deduplicator, input->InputAt(i), types->at(i),
631               kind, zone);
632         }
633         return entries;
634       } else {
635         // Deoptimizer counts duplicate objects for the running id, so we have
636         // to push the input again.
637         deduplicator->InsertObject(input);
638         values->PushDuplicate(id);
639         return 0;
640       }
641     }
642     default: {
643       InstructionOperand op =
644           OperandForDeopt(isolate(), g, input, kind, type.representation());
645       if (op.kind() == InstructionOperand::INVALID) {
646         // Invalid operand means the value is impossible or optimized-out.
647         values->PushOptimizedOut();
648         return 0;
649       } else {
650         inputs->push_back(op);
651         values->PushPlain(type);
652         return 1;
653       }
654     }
655   }
656 }
657 
658 struct InstructionSelector::CachedStateValues : public ZoneObject {
659  public:
CachedStateValuesv8::internal::compiler::InstructionSelector::CachedStateValues660   CachedStateValues(Zone* zone, StateValueList* values, size_t values_start,
661                     InstructionOperandVector* inputs, size_t inputs_start)
662       : inputs_(inputs->begin() + inputs_start, inputs->end(), zone),
663         values_(values->MakeSlice(values_start)) {}
664 
Emitv8::internal::compiler::InstructionSelector::CachedStateValues665   size_t Emit(InstructionOperandVector* inputs, StateValueList* values) {
666     inputs->insert(inputs->end(), inputs_.begin(), inputs_.end());
667     values->PushCachedSlice(values_);
668     return inputs_.size();
669   }
670 
671  private:
672   InstructionOperandVector inputs_;
673   StateValueList::Slice values_;
674 };
675 
676 class InstructionSelector::CachedStateValuesBuilder {
677  public:
CachedStateValuesBuilder(StateValueList * values,InstructionOperandVector * inputs,StateObjectDeduplicator * deduplicator)678   explicit CachedStateValuesBuilder(StateValueList* values,
679                                     InstructionOperandVector* inputs,
680                                     StateObjectDeduplicator* deduplicator)
681       : values_(values),
682         inputs_(inputs),
683         deduplicator_(deduplicator),
684         values_start_(values->size()),
685         nested_start_(values->nested_count()),
686         inputs_start_(inputs->size()),
687         deduplicator_start_(deduplicator->size()) {}
688 
689   // We can only build a CachedStateValues for a StateValue if it didn't update
690   // any of the ids in the deduplicator.
CanCache() const691   bool CanCache() const { return deduplicator_->size() == deduplicator_start_; }
692 
Build(Zone * zone)693   InstructionSelector::CachedStateValues* Build(Zone* zone) {
694     DCHECK(CanCache());
695     DCHECK(values_->nested_count() == nested_start_);
696     return zone->New<InstructionSelector::CachedStateValues>(
697         zone, values_, values_start_, inputs_, inputs_start_);
698   }
699 
700  private:
701   StateValueList* values_;
702   InstructionOperandVector* inputs_;
703   StateObjectDeduplicator* deduplicator_;
704   size_t values_start_;
705   size_t nested_start_;
706   size_t inputs_start_;
707   size_t deduplicator_start_;
708 };
709 
AddInputsToFrameStateDescriptor(StateValueList * values,InstructionOperandVector * inputs,OperandGenerator * g,StateObjectDeduplicator * deduplicator,Node * node,FrameStateInputKind kind,Zone * zone)710 size_t InstructionSelector::AddInputsToFrameStateDescriptor(
711     StateValueList* values, InstructionOperandVector* inputs,
712     OperandGenerator* g, StateObjectDeduplicator* deduplicator, Node* node,
713     FrameStateInputKind kind, Zone* zone) {
714   // StateValues are often shared across different nodes, and processing them is
715   // expensive, so cache the result of processing a StateValue so that we can
716   // quickly copy the result if we see it again.
717   FrameStateInput key(node, kind);
718   auto cache_entry = state_values_cache_.find(key);
719   if (cache_entry != state_values_cache_.end()) {
720     // Entry found in cache, emit cached version.
721     return cache_entry->second->Emit(inputs, values);
722   } else {
723     // Not found in cache, generate and then store in cache if possible.
724     size_t entries = 0;
725     CachedStateValuesBuilder cache_builder(values, inputs, deduplicator);
726     StateValuesAccess::iterator it = StateValuesAccess(node).begin();
727     // Take advantage of sparse nature of StateValuesAccess to skip over
728     // multiple empty nodes at once pushing repeated OptimizedOuts all in one
729     // go.
730     while (!it.done()) {
731       values->PushOptimizedOut(it.AdvanceTillNotEmpty());
732       if (it.done()) break;
733       StateValuesAccess::TypedNode input_node = *it;
734       entries += AddOperandToStateValueDescriptor(values, inputs, g,
735                                                   deduplicator, input_node.node,
736                                                   input_node.type, kind, zone);
737       ++it;
738     }
739     if (cache_builder.CanCache()) {
740       // Use this->zone() to build the cache entry in the instruction selector's
741       // zone rather than the more long-lived instruction zone.
742       state_values_cache_.emplace(key, cache_builder.Build(this->zone()));
743     }
744     return entries;
745   }
746 }
747 
748 // Returns the number of instruction operands added to inputs.
AddInputsToFrameStateDescriptor(FrameStateDescriptor * descriptor,FrameState state,OperandGenerator * g,StateObjectDeduplicator * deduplicator,InstructionOperandVector * inputs,FrameStateInputKind kind,Zone * zone)749 size_t InstructionSelector::AddInputsToFrameStateDescriptor(
750     FrameStateDescriptor* descriptor, FrameState state, OperandGenerator* g,
751     StateObjectDeduplicator* deduplicator, InstructionOperandVector* inputs,
752     FrameStateInputKind kind, Zone* zone) {
753   size_t entries = 0;
754   size_t initial_size = inputs->size();
755   USE(initial_size);  // initial_size is only used for debug.
756 
757   if (descriptor->outer_state()) {
758     entries += AddInputsToFrameStateDescriptor(
759         descriptor->outer_state(), FrameState{state.outer_frame_state()}, g,
760         deduplicator, inputs, kind, zone);
761   }
762 
763   Node* parameters = state.parameters();
764   Node* locals = state.locals();
765   Node* stack = state.stack();
766   Node* context = state.context();
767   Node* function = state.function();
768 
769   DCHECK_EQ(descriptor->parameters_count(),
770             StateValuesAccess(parameters).size());
771   DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
772   DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
773 
774   StateValueList* values_descriptor = descriptor->GetStateValueDescriptors();
775 
776   DCHECK_EQ(values_descriptor->size(), 0u);
777   values_descriptor->ReserveSize(descriptor->GetSize());
778 
779   DCHECK_NOT_NULL(function);
780   entries += AddOperandToStateValueDescriptor(
781       values_descriptor, inputs, g, deduplicator, function,
782       MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
783 
784   entries += AddInputsToFrameStateDescriptor(
785       values_descriptor, inputs, g, deduplicator, parameters, kind, zone);
786 
787   if (descriptor->HasContext()) {
788     DCHECK_NOT_NULL(context);
789     entries += AddOperandToStateValueDescriptor(
790         values_descriptor, inputs, g, deduplicator, context,
791         MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
792   }
793 
794   entries += AddInputsToFrameStateDescriptor(values_descriptor, inputs, g,
795                                              deduplicator, locals, kind, zone);
796   entries += AddInputsToFrameStateDescriptor(values_descriptor, inputs, g,
797                                              deduplicator, stack, kind, zone);
798   DCHECK_EQ(initial_size + entries, inputs->size());
799   return entries;
800 }
801 
EmitWithContinuation(InstructionCode opcode,InstructionOperand a,FlagsContinuation * cont)802 Instruction* InstructionSelector::EmitWithContinuation(
803     InstructionCode opcode, InstructionOperand a, FlagsContinuation* cont) {
804   return EmitWithContinuation(opcode, 0, nullptr, 1, &a, cont);
805 }
806 
EmitWithContinuation(InstructionCode opcode,InstructionOperand a,InstructionOperand b,FlagsContinuation * cont)807 Instruction* InstructionSelector::EmitWithContinuation(
808     InstructionCode opcode, InstructionOperand a, InstructionOperand b,
809     FlagsContinuation* cont) {
810   InstructionOperand inputs[] = {a, b};
811   return EmitWithContinuation(opcode, 0, nullptr, arraysize(inputs), inputs,
812                               cont);
813 }
814 
EmitWithContinuation(InstructionCode opcode,InstructionOperand a,InstructionOperand b,InstructionOperand c,FlagsContinuation * cont)815 Instruction* InstructionSelector::EmitWithContinuation(
816     InstructionCode opcode, InstructionOperand a, InstructionOperand b,
817     InstructionOperand c, FlagsContinuation* cont) {
818   InstructionOperand inputs[] = {a, b, c};
819   return EmitWithContinuation(opcode, 0, nullptr, arraysize(inputs), inputs,
820                               cont);
821 }
822 
EmitWithContinuation(InstructionCode opcode,size_t output_count,InstructionOperand * outputs,size_t input_count,InstructionOperand * inputs,FlagsContinuation * cont)823 Instruction* InstructionSelector::EmitWithContinuation(
824     InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
825     size_t input_count, InstructionOperand* inputs, FlagsContinuation* cont) {
826   return EmitWithContinuation(opcode, output_count, outputs, input_count,
827                               inputs, 0, nullptr, cont);
828 }
829 
EmitWithContinuation(InstructionCode opcode,size_t output_count,InstructionOperand * outputs,size_t input_count,InstructionOperand * inputs,size_t temp_count,InstructionOperand * temps,FlagsContinuation * cont)830 Instruction* InstructionSelector::EmitWithContinuation(
831     InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
832     size_t input_count, InstructionOperand* inputs, size_t temp_count,
833     InstructionOperand* temps, FlagsContinuation* cont) {
834   OperandGenerator g(this);
835 
836   opcode = cont->Encode(opcode);
837 
838   continuation_inputs_.resize(0);
839   for (size_t i = 0; i < input_count; i++) {
840     continuation_inputs_.push_back(inputs[i]);
841   }
842 
843   continuation_outputs_.resize(0);
844   for (size_t i = 0; i < output_count; i++) {
845     continuation_outputs_.push_back(outputs[i]);
846   }
847 
848   continuation_temps_.resize(0);
849   for (size_t i = 0; i < temp_count; i++) {
850     continuation_temps_.push_back(temps[i]);
851   }
852 
853   if (cont->IsBranch()) {
854     continuation_inputs_.push_back(g.Label(cont->true_block()));
855     continuation_inputs_.push_back(g.Label(cont->false_block()));
856   } else if (cont->IsDeoptimize()) {
857     int immediate_args_count = 0;
858     opcode |= DeoptImmedArgsCountField::encode(immediate_args_count) |
859               DeoptFrameStateOffsetField::encode(static_cast<int>(input_count));
860     AppendDeoptimizeArguments(&continuation_inputs_, cont->reason(),
861                               cont->node_id(), cont->feedback(),
862                               FrameState{cont->frame_state()});
863   } else if (cont->IsSet()) {
864     continuation_outputs_.push_back(g.DefineAsRegister(cont->result()));
865   } else if (cont->IsSelect()) {
866     // The {Select} should put one of two values into the output register,
867     // depending on the result of the condition. The two result values are in
868     // the last two input slots, the {false_value} in {input_count - 2}, and the
869     // true_value in {input_count - 1}. The other inputs are used for the
870     // condition.
871     AddOutputToSelectContinuation(&g, static_cast<int>(input_count) - 2,
872                                   cont->result());
873   } else if (cont->IsTrap()) {
874     int trap_id = static_cast<int>(cont->trap_id());
875     continuation_inputs_.push_back(g.UseImmediate(trap_id));
876   } else {
877     DCHECK(cont->IsNone());
878   }
879 
880   size_t const emit_inputs_size = continuation_inputs_.size();
881   auto* emit_inputs =
882       emit_inputs_size ? &continuation_inputs_.front() : nullptr;
883   size_t const emit_outputs_size = continuation_outputs_.size();
884   auto* emit_outputs =
885       emit_outputs_size ? &continuation_outputs_.front() : nullptr;
886   size_t const emit_temps_size = continuation_temps_.size();
887   auto* emit_temps = emit_temps_size ? &continuation_temps_.front() : nullptr;
888   return Emit(opcode, emit_outputs_size, emit_outputs, emit_inputs_size,
889               emit_inputs, emit_temps_size, emit_temps);
890 }
891 
AppendDeoptimizeArguments(InstructionOperandVector * args,DeoptimizeReason reason,NodeId node_id,FeedbackSource const & feedback,FrameState frame_state)892 void InstructionSelector::AppendDeoptimizeArguments(
893     InstructionOperandVector* args, DeoptimizeReason reason, NodeId node_id,
894     FeedbackSource const& feedback, FrameState frame_state) {
895   OperandGenerator g(this);
896   FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state);
897   int const state_id = sequence()->AddDeoptimizationEntry(
898       descriptor, DeoptimizeKind::kEager, reason, node_id, feedback);
899   args->push_back(g.TempImmediate(state_id));
900   StateObjectDeduplicator deduplicator(instruction_zone());
901   AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator,
902                                   args, FrameStateInputKind::kAny,
903                                   instruction_zone());
904 }
905 
906 // An internal helper class for generating the operands to calls.
907 // TODO(bmeurer): Get rid of the CallBuffer business and make
908 // InstructionSelector::VisitCall platform independent instead.
909 struct CallBuffer {
CallBufferv8::internal::compiler::CallBuffer910   CallBuffer(Zone* zone, const CallDescriptor* call_descriptor,
911              FrameStateDescriptor* frame_state)
912       : descriptor(call_descriptor),
913         frame_state_descriptor(frame_state),
914         output_nodes(zone),
915         outputs(zone),
916         instruction_args(zone),
917         pushed_nodes(zone) {
918     output_nodes.reserve(call_descriptor->ReturnCount());
919     outputs.reserve(call_descriptor->ReturnCount());
920     pushed_nodes.reserve(input_count());
921     instruction_args.reserve(input_count() + frame_state_value_count());
922   }
923 
924   const CallDescriptor* descriptor;
925   FrameStateDescriptor* frame_state_descriptor;
926   ZoneVector<PushParameter> output_nodes;
927   InstructionOperandVector outputs;
928   InstructionOperandVector instruction_args;
929   ZoneVector<PushParameter> pushed_nodes;
930 
input_countv8::internal::compiler::CallBuffer931   size_t input_count() const { return descriptor->InputCount(); }
932 
frame_state_countv8::internal::compiler::CallBuffer933   size_t frame_state_count() const { return descriptor->FrameStateCount(); }
934 
frame_state_value_countv8::internal::compiler::CallBuffer935   size_t frame_state_value_count() const {
936     return (frame_state_descriptor == nullptr)
937                ? 0
938                : (frame_state_descriptor->GetTotalSize() +
939                   1);  // Include deopt id.
940   }
941 };
942 
943 // TODO(bmeurer): Get rid of the CallBuffer business and make
944 // InstructionSelector::VisitCall platform independent instead.
InitializeCallBuffer(Node * call,CallBuffer * buffer,CallBufferFlags flags,int stack_param_delta)945 void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
946                                                CallBufferFlags flags,
947                                                int stack_param_delta) {
948   OperandGenerator g(this);
949   size_t ret_count = buffer->descriptor->ReturnCount();
950   bool is_tail_call = (flags & kCallTail) != 0;
951   DCHECK_LE(call->op()->ValueOutputCount(), ret_count);
952   DCHECK_EQ(
953       call->op()->ValueInputCount(),
954       static_cast<int>(buffer->input_count() + buffer->frame_state_count()));
955 
956   if (ret_count > 0) {
957     // Collect the projections that represent multiple outputs from this call.
958     if (ret_count == 1) {
959       PushParameter result = {call, buffer->descriptor->GetReturnLocation(0)};
960       buffer->output_nodes.push_back(result);
961     } else {
962       buffer->output_nodes.resize(ret_count);
963       for (size_t i = 0; i < ret_count; ++i) {
964         LinkageLocation location = buffer->descriptor->GetReturnLocation(i);
965         buffer->output_nodes[i] = PushParameter(nullptr, location);
966       }
967       for (Edge const edge : call->use_edges()) {
968         if (!NodeProperties::IsValueEdge(edge)) continue;
969         Node* node = edge.from();
970         DCHECK_EQ(IrOpcode::kProjection, node->opcode());
971         size_t const index = ProjectionIndexOf(node->op());
972 
973         DCHECK_LT(index, buffer->output_nodes.size());
974         DCHECK(!buffer->output_nodes[index].node);
975         buffer->output_nodes[index].node = node;
976       }
977 
978       frame_->EnsureReturnSlots(
979           static_cast<int>(buffer->descriptor->ReturnSlotCount()));
980     }
981 
982     // Filter out the outputs that aren't live because no projection uses them.
983     size_t outputs_needed_by_framestate =
984         buffer->frame_state_descriptor == nullptr
985             ? 0
986             : buffer->frame_state_descriptor->state_combine()
987                   .ConsumedOutputCount();
988     for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
989       bool output_is_live = buffer->output_nodes[i].node != nullptr ||
990                             i < outputs_needed_by_framestate;
991       if (output_is_live) {
992         LinkageLocation location = buffer->output_nodes[i].location;
993         MachineRepresentation rep = location.GetType().representation();
994 
995         Node* output = buffer->output_nodes[i].node;
996         InstructionOperand op = output == nullptr
997                                     ? g.TempLocation(location)
998                                     : g.DefineAsLocation(output, location);
999         MarkAsRepresentation(rep, op);
1000 
1001         if (!UnallocatedOperand::cast(op).HasFixedSlotPolicy()) {
1002           buffer->outputs.push_back(op);
1003           buffer->output_nodes[i].node = nullptr;
1004         }
1005       }
1006     }
1007   }
1008 
1009   // The first argument is always the callee code.
1010   Node* callee = call->InputAt(0);
1011   bool call_code_immediate = (flags & kCallCodeImmediate) != 0;
1012   bool call_address_immediate = (flags & kCallAddressImmediate) != 0;
1013   bool call_use_fixed_target_reg = (flags & kCallFixedTargetRegister) != 0;
1014   switch (buffer->descriptor->kind()) {
1015     case CallDescriptor::kCallCodeObject:
1016       buffer->instruction_args.push_back(
1017           (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant)
1018               ? g.UseImmediate(callee)
1019               : call_use_fixed_target_reg
1020                     ? g.UseFixed(callee, kJavaScriptCallCodeStartRegister)
1021                     : g.UseRegister(callee));
1022       break;
1023     case CallDescriptor::kCallAddress:
1024       buffer->instruction_args.push_back(
1025           (call_address_immediate &&
1026            callee->opcode() == IrOpcode::kExternalConstant)
1027               ? g.UseImmediate(callee)
1028               : call_use_fixed_target_reg
1029                     ? g.UseFixed(callee, kJavaScriptCallCodeStartRegister)
1030                     : g.UseRegister(callee));
1031       break;
1032 #if V8_ENABLE_WEBASSEMBLY
1033     case CallDescriptor::kCallWasmCapiFunction:
1034     case CallDescriptor::kCallWasmFunction:
1035     case CallDescriptor::kCallWasmImportWrapper:
1036       buffer->instruction_args.push_back(
1037           (call_address_immediate &&
1038            (callee->opcode() == IrOpcode::kRelocatableInt64Constant ||
1039             callee->opcode() == IrOpcode::kRelocatableInt32Constant))
1040               ? g.UseImmediate(callee)
1041               : call_use_fixed_target_reg
1042                     ? g.UseFixed(callee, kJavaScriptCallCodeStartRegister)
1043                     : g.UseRegister(callee));
1044       break;
1045 #endif  // V8_ENABLE_WEBASSEMBLY
1046     case CallDescriptor::kCallBuiltinPointer:
1047       // The common case for builtin pointers is to have the target in a
1048       // register. If we have a constant, we use a register anyway to simplify
1049       // related code.
1050       buffer->instruction_args.push_back(
1051           call_use_fixed_target_reg
1052               ? g.UseFixed(callee, kJavaScriptCallCodeStartRegister)
1053               : g.UseRegister(callee));
1054       break;
1055     case CallDescriptor::kCallJSFunction:
1056       buffer->instruction_args.push_back(
1057           g.UseLocation(callee, buffer->descriptor->GetInputLocation(0)));
1058       break;
1059   }
1060   DCHECK_EQ(1u, buffer->instruction_args.size());
1061 
1062   // If the call needs a frame state, we insert the state information as
1063   // follows (n is the number of value inputs to the frame state):
1064   // arg 1               : deoptimization id.
1065   // arg 2 - arg (n + 2) : value inputs to the frame state.
1066   size_t frame_state_entries = 0;
1067   USE(frame_state_entries);  // frame_state_entries is only used for debug.
1068   if (buffer->frame_state_descriptor != nullptr) {
1069     FrameState frame_state{
1070         call->InputAt(static_cast<int>(buffer->descriptor->InputCount()))};
1071 
1072     // If it was a syntactic tail call we need to drop the current frame and
1073     // all the frames on top of it that are either an arguments adaptor frame
1074     // or a tail caller frame.
1075     if (is_tail_call) {
1076       frame_state = FrameState{NodeProperties::GetFrameStateInput(frame_state)};
1077       buffer->frame_state_descriptor =
1078           buffer->frame_state_descriptor->outer_state();
1079       while (buffer->frame_state_descriptor != nullptr &&
1080              buffer->frame_state_descriptor->type() ==
1081                  FrameStateType::kArgumentsAdaptor) {
1082         frame_state =
1083             FrameState{NodeProperties::GetFrameStateInput(frame_state)};
1084         buffer->frame_state_descriptor =
1085             buffer->frame_state_descriptor->outer_state();
1086       }
1087     }
1088 
1089     int const state_id = sequence()->AddDeoptimizationEntry(
1090         buffer->frame_state_descriptor, DeoptimizeKind::kLazy,
1091         DeoptimizeReason::kUnknown, call->id(), FeedbackSource());
1092     buffer->instruction_args.push_back(g.TempImmediate(state_id));
1093 
1094     StateObjectDeduplicator deduplicator(instruction_zone());
1095 
1096     frame_state_entries =
1097         1 + AddInputsToFrameStateDescriptor(
1098                 buffer->frame_state_descriptor, frame_state, &g, &deduplicator,
1099                 &buffer->instruction_args, FrameStateInputKind::kStackSlot,
1100                 instruction_zone());
1101 
1102     DCHECK_EQ(1 + frame_state_entries, buffer->instruction_args.size());
1103   }
1104 
1105   size_t input_count = static_cast<size_t>(buffer->input_count());
1106 
1107   // Split the arguments into pushed_nodes and instruction_args. Pushed
1108   // arguments require an explicit push instruction before the call and do
1109   // not appear as arguments to the call. Everything else ends up
1110   // as an InstructionOperand argument to the call.
1111   auto iter(call->inputs().begin());
1112   size_t pushed_count = 0;
1113   for (size_t index = 0; index < input_count; ++iter, ++index) {
1114     DCHECK(iter != call->inputs().end());
1115     DCHECK_NE(IrOpcode::kFrameState, (*iter)->op()->opcode());
1116     if (index == 0) continue;  // The first argument (callee) is already done.
1117 
1118     LinkageLocation location = buffer->descriptor->GetInputLocation(index);
1119     if (is_tail_call) {
1120       location = LinkageLocation::ConvertToTailCallerLocation(
1121           location, stack_param_delta);
1122     }
1123     InstructionOperand op = g.UseLocation(*iter, location);
1124     UnallocatedOperand unallocated = UnallocatedOperand::cast(op);
1125     if (unallocated.HasFixedSlotPolicy() && !is_tail_call) {
1126       int stack_index = buffer->descriptor->GetStackIndexFromSlot(
1127           unallocated.fixed_slot_index());
1128       // This can insert empty slots before stack_index and will insert enough
1129       // slots after stack_index to store the parameter.
1130       if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
1131         int num_slots = location.GetSizeInPointers();
1132         buffer->pushed_nodes.resize(stack_index + num_slots);
1133       }
1134       PushParameter param = {*iter, location};
1135       buffer->pushed_nodes[stack_index] = param;
1136       pushed_count++;
1137     } else {
1138       buffer->instruction_args.push_back(op);
1139     }
1140   }
1141   DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count -
1142                              frame_state_entries);
1143   USE(pushed_count);
1144   if (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK && is_tail_call &&
1145       stack_param_delta != 0) {
1146     // For tail calls that change the size of their parameter list and keep
1147     // their return address on the stack, move the return address to just above
1148     // the parameters.
1149     LinkageLocation saved_return_location =
1150         LinkageLocation::ForSavedCallerReturnAddress();
1151     InstructionOperand return_address =
1152         g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation(
1153                                  saved_return_location, stack_param_delta),
1154                              saved_return_location);
1155     buffer->instruction_args.push_back(return_address);
1156   }
1157 }
1158 
IsSourcePositionUsed(Node * node)1159 bool InstructionSelector::IsSourcePositionUsed(Node* node) {
1160   return (source_position_mode_ == kAllSourcePositions ||
1161           node->opcode() == IrOpcode::kCall ||
1162           node->opcode() == IrOpcode::kTrapIf ||
1163           node->opcode() == IrOpcode::kTrapUnless ||
1164           node->opcode() == IrOpcode::kProtectedLoad ||
1165           node->opcode() == IrOpcode::kProtectedStore);
1166 }
1167 
VisitBlock(BasicBlock * block)1168 void InstructionSelector::VisitBlock(BasicBlock* block) {
1169   DCHECK(!current_block_);
1170   current_block_ = block;
1171   auto current_num_instructions = [&] {
1172     DCHECK_GE(kMaxInt, instructions_.size());
1173     return static_cast<int>(instructions_.size());
1174   };
1175   int current_block_end = current_num_instructions();
1176 
1177   int effect_level = 0;
1178   for (Node* const node : *block) {
1179     SetEffectLevel(node, effect_level);
1180     current_effect_level_ = effect_level;
1181     if (node->opcode() == IrOpcode::kStore ||
1182         node->opcode() == IrOpcode::kUnalignedStore ||
1183         node->opcode() == IrOpcode::kCall ||
1184         node->opcode() == IrOpcode::kProtectedStore ||
1185 #define ADD_EFFECT_FOR_ATOMIC_OP(Opcode) \
1186   node->opcode() == IrOpcode::k##Opcode ||
1187         MACHINE_ATOMIC_OP_LIST(ADD_EFFECT_FOR_ATOMIC_OP)
1188 #undef ADD_EFFECT_FOR_ATOMIC_OP
1189                 node->opcode() == IrOpcode::kMemoryBarrier) {
1190       ++effect_level;
1191     }
1192   }
1193 
1194   // We visit the control first, then the nodes in the block, so the block's
1195   // control input should be on the same effect level as the last node.
1196   if (block->control_input() != nullptr) {
1197     SetEffectLevel(block->control_input(), effect_level);
1198     current_effect_level_ = effect_level;
1199   }
1200 
1201   auto FinishEmittedInstructions = [&](Node* node, int instruction_start) {
1202     if (instruction_selection_failed()) return false;
1203     if (current_num_instructions() == instruction_start) return true;
1204     std::reverse(instructions_.begin() + instruction_start,
1205                  instructions_.end());
1206     if (!node) return true;
1207     if (!source_positions_) return true;
1208     SourcePosition source_position = source_positions_->GetSourcePosition(node);
1209     if (source_position.IsKnown() && IsSourcePositionUsed(node)) {
1210       sequence()->SetSourcePosition(instructions_.back(), source_position);
1211     }
1212     return true;
1213   };
1214 
1215   // Generate code for the block control "top down", but schedule the code
1216   // "bottom up".
1217   VisitControl(block);
1218   if (!FinishEmittedInstructions(block->control_input(), current_block_end)) {
1219     return;
1220   }
1221 
1222   // Visit code in reverse control flow order, because architecture-specific
1223   // matching may cover more than one node at a time.
1224   for (auto node : base::Reversed(*block)) {
1225     int current_node_end = current_num_instructions();
1226     // Skip nodes that are unused or already defined.
1227     if (IsUsed(node) && !IsDefined(node)) {
1228       // Generate code for this node "top down", but schedule the code "bottom
1229       // up".
1230       VisitNode(node);
1231       if (!FinishEmittedInstructions(node, current_node_end)) return;
1232     }
1233     if (trace_turbo_ == kEnableTraceTurboJson) {
1234       instr_origins_[node->id()] = {current_num_instructions(),
1235                                     current_node_end};
1236     }
1237   }
1238 
1239   // We're done with the block.
1240   InstructionBlock* instruction_block =
1241       sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
1242   if (current_num_instructions() == current_block_end) {
1243     // Avoid empty block: insert a {kArchNop} instruction.
1244     Emit(Instruction::New(sequence()->zone(), kArchNop));
1245   }
1246   instruction_block->set_code_start(current_num_instructions());
1247   instruction_block->set_code_end(current_block_end);
1248   current_block_ = nullptr;
1249 }
1250 
VisitControl(BasicBlock * block)1251 void InstructionSelector::VisitControl(BasicBlock* block) {
1252 #ifdef DEBUG
1253   // SSA deconstruction requires targets of branches not to have phis.
1254   // Edge split form guarantees this property, but is more strict.
1255   if (block->SuccessorCount() > 1) {
1256     for (BasicBlock* const successor : block->successors()) {
1257       for (Node* const node : *successor) {
1258         if (IrOpcode::IsPhiOpcode(node->opcode())) {
1259           std::ostringstream str;
1260           str << "You might have specified merged variables for a label with "
1261               << "only one predecessor." << std::endl
1262               << "# Current Block: " << *successor << std::endl
1263               << "#          Node: " << *node;
1264           FATAL("%s", str.str().c_str());
1265         }
1266       }
1267     }
1268   }
1269 #endif
1270 
1271   Node* input = block->control_input();
1272   int instruction_end = static_cast<int>(instructions_.size());
1273   switch (block->control()) {
1274     case BasicBlock::kGoto:
1275       VisitGoto(block->SuccessorAt(0));
1276       break;
1277     case BasicBlock::kCall: {
1278       DCHECK_EQ(IrOpcode::kCall, input->opcode());
1279       BasicBlock* success = block->SuccessorAt(0);
1280       BasicBlock* exception = block->SuccessorAt(1);
1281       VisitCall(input, exception);
1282       VisitGoto(success);
1283       break;
1284     }
1285     case BasicBlock::kTailCall: {
1286       DCHECK_EQ(IrOpcode::kTailCall, input->opcode());
1287       VisitTailCall(input);
1288       break;
1289     }
1290     case BasicBlock::kBranch: {
1291       DCHECK_EQ(IrOpcode::kBranch, input->opcode());
1292       BasicBlock* tbranch = block->SuccessorAt(0);
1293       BasicBlock* fbranch = block->SuccessorAt(1);
1294       if (tbranch == fbranch) {
1295         VisitGoto(tbranch);
1296       } else {
1297         VisitBranch(input, tbranch, fbranch);
1298       }
1299       break;
1300     }
1301     case BasicBlock::kSwitch: {
1302       DCHECK_EQ(IrOpcode::kSwitch, input->opcode());
1303       // Last successor must be {IfDefault}.
1304       BasicBlock* default_branch = block->successors().back();
1305       DCHECK_EQ(IrOpcode::kIfDefault, default_branch->front()->opcode());
1306       // All other successors must be {IfValue}s.
1307       int32_t min_value = std::numeric_limits<int32_t>::max();
1308       int32_t max_value = std::numeric_limits<int32_t>::min();
1309       size_t case_count = block->SuccessorCount() - 1;
1310       ZoneVector<CaseInfo> cases(case_count, zone());
1311       for (size_t i = 0; i < case_count; ++i) {
1312         BasicBlock* branch = block->SuccessorAt(i);
1313         const IfValueParameters& p = IfValueParametersOf(branch->front()->op());
1314         cases[i] = CaseInfo{p.value(), p.comparison_order(), branch};
1315         if (min_value > p.value()) min_value = p.value();
1316         if (max_value < p.value()) max_value = p.value();
1317       }
1318       SwitchInfo sw(cases, min_value, max_value, default_branch);
1319       VisitSwitch(input, sw);
1320       break;
1321     }
1322     case BasicBlock::kReturn: {
1323       DCHECK_EQ(IrOpcode::kReturn, input->opcode());
1324       VisitReturn(input);
1325       break;
1326     }
1327     case BasicBlock::kDeoptimize: {
1328       DeoptimizeParameters p = DeoptimizeParametersOf(input->op());
1329       FrameState value{input->InputAt(0)};
1330       VisitDeoptimize(p.reason(), input->id(), p.feedback(), value);
1331       break;
1332     }
1333     case BasicBlock::kThrow:
1334       DCHECK_EQ(IrOpcode::kThrow, input->opcode());
1335       VisitThrow(input);
1336       break;
1337     case BasicBlock::kNone: {
1338       // Exit block doesn't have control.
1339       DCHECK_NULL(input);
1340       break;
1341     }
1342     default:
1343       UNREACHABLE();
1344   }
1345   if (trace_turbo_ == kEnableTraceTurboJson && input) {
1346     int instruction_start = static_cast<int>(instructions_.size());
1347     instr_origins_[input->id()] = {instruction_start, instruction_end};
1348   }
1349 }
1350 
MarkPairProjectionsAsWord32(Node * node)1351 void InstructionSelector::MarkPairProjectionsAsWord32(Node* node) {
1352   Node* projection0 = NodeProperties::FindProjection(node, 0);
1353   if (projection0) {
1354     MarkAsWord32(projection0);
1355   }
1356   Node* projection1 = NodeProperties::FindProjection(node, 1);
1357   if (projection1) {
1358     MarkAsWord32(projection1);
1359   }
1360 }
1361 
VisitNode(Node * node)1362 void InstructionSelector::VisitNode(Node* node) {
1363   tick_counter_->TickAndMaybeEnterSafepoint();
1364   DCHECK_NOT_NULL(schedule()->block(node));  // should only use scheduled nodes.
1365   switch (node->opcode()) {
1366     case IrOpcode::kStart:
1367     case IrOpcode::kLoop:
1368     case IrOpcode::kEnd:
1369     case IrOpcode::kBranch:
1370     case IrOpcode::kIfTrue:
1371     case IrOpcode::kIfFalse:
1372     case IrOpcode::kIfSuccess:
1373     case IrOpcode::kSwitch:
1374     case IrOpcode::kIfValue:
1375     case IrOpcode::kIfDefault:
1376     case IrOpcode::kEffectPhi:
1377     case IrOpcode::kMerge:
1378     case IrOpcode::kTerminate:
1379     case IrOpcode::kBeginRegion:
1380       // No code needed for these graph artifacts.
1381       return;
1382     case IrOpcode::kIfException:
1383       return MarkAsTagged(node), VisitIfException(node);
1384     case IrOpcode::kFinishRegion:
1385       return MarkAsTagged(node), VisitFinishRegion(node);
1386     case IrOpcode::kParameter: {
1387       // Parameters should always be scheduled to the first block.
1388       DCHECK_EQ(schedule()->block(node)->rpo_number(), 0);
1389       MachineType type =
1390           linkage()->GetParameterType(ParameterIndexOf(node->op()));
1391       MarkAsRepresentation(type.representation(), node);
1392       return VisitParameter(node);
1393     }
1394     case IrOpcode::kOsrValue:
1395       return MarkAsTagged(node), VisitOsrValue(node);
1396     case IrOpcode::kPhi: {
1397       MachineRepresentation rep = PhiRepresentationOf(node->op());
1398       if (rep == MachineRepresentation::kNone) return;
1399       MarkAsRepresentation(rep, node);
1400       return VisitPhi(node);
1401     }
1402     case IrOpcode::kProjection:
1403       return VisitProjection(node);
1404     case IrOpcode::kInt32Constant:
1405     case IrOpcode::kInt64Constant:
1406     case IrOpcode::kTaggedIndexConstant:
1407     case IrOpcode::kExternalConstant:
1408     case IrOpcode::kRelocatableInt32Constant:
1409     case IrOpcode::kRelocatableInt64Constant:
1410       return VisitConstant(node);
1411     case IrOpcode::kFloat32Constant:
1412       return MarkAsFloat32(node), VisitConstant(node);
1413     case IrOpcode::kFloat64Constant:
1414       return MarkAsFloat64(node), VisitConstant(node);
1415     case IrOpcode::kHeapConstant:
1416       return MarkAsTagged(node), VisitConstant(node);
1417     case IrOpcode::kCompressedHeapConstant:
1418       return MarkAsCompressed(node), VisitConstant(node);
1419     case IrOpcode::kNumberConstant: {
1420       double value = OpParameter<double>(node->op());
1421       if (!IsSmiDouble(value)) MarkAsTagged(node);
1422       return VisitConstant(node);
1423     }
1424     case IrOpcode::kDelayedStringConstant:
1425       return MarkAsTagged(node), VisitConstant(node);
1426     case IrOpcode::kCall:
1427       return VisitCall(node);
1428     case IrOpcode::kDeoptimizeIf:
1429       return VisitDeoptimizeIf(node);
1430     case IrOpcode::kDeoptimizeUnless:
1431       return VisitDeoptimizeUnless(node);
1432     case IrOpcode::kTrapIf:
1433       return VisitTrapIf(node, TrapIdOf(node->op()));
1434     case IrOpcode::kTrapUnless:
1435       return VisitTrapUnless(node, TrapIdOf(node->op()));
1436     case IrOpcode::kFrameState:
1437     case IrOpcode::kStateValues:
1438     case IrOpcode::kObjectState:
1439       return;
1440     case IrOpcode::kAbortCSADcheck:
1441       VisitAbortCSADcheck(node);
1442       return;
1443     case IrOpcode::kDebugBreak:
1444       VisitDebugBreak(node);
1445       return;
1446     case IrOpcode::kUnreachable:
1447       VisitUnreachable(node);
1448       return;
1449     case IrOpcode::kStaticAssert:
1450       VisitStaticAssert(node);
1451       return;
1452     case IrOpcode::kDeadValue:
1453       VisitDeadValue(node);
1454       return;
1455     case IrOpcode::kComment:
1456       VisitComment(node);
1457       return;
1458     case IrOpcode::kRetain:
1459       VisitRetain(node);
1460       return;
1461     case IrOpcode::kLoad:
1462     case IrOpcode::kLoadImmutable: {
1463       LoadRepresentation type = LoadRepresentationOf(node->op());
1464       MarkAsRepresentation(type.representation(), node);
1465       return VisitLoad(node);
1466     }
1467     case IrOpcode::kLoadTransform: {
1468       MarkAsRepresentation(MachineRepresentation::kSimd128, node);
1469       return VisitLoadTransform(node);
1470     }
1471     case IrOpcode::kLoadLane: {
1472       MarkAsRepresentation(MachineRepresentation::kSimd128, node);
1473       return VisitLoadLane(node);
1474     }
1475     case IrOpcode::kStore:
1476       return VisitStore(node);
1477     case IrOpcode::kProtectedStore:
1478       return VisitProtectedStore(node);
1479     case IrOpcode::kStoreLane: {
1480       MarkAsRepresentation(MachineRepresentation::kSimd128, node);
1481       return VisitStoreLane(node);
1482     }
1483     case IrOpcode::kWord32And:
1484       return MarkAsWord32(node), VisitWord32And(node);
1485     case IrOpcode::kWord32Or:
1486       return MarkAsWord32(node), VisitWord32Or(node);
1487     case IrOpcode::kWord32Xor:
1488       return MarkAsWord32(node), VisitWord32Xor(node);
1489     case IrOpcode::kWord32Shl:
1490       return MarkAsWord32(node), VisitWord32Shl(node);
1491     case IrOpcode::kWord32Shr:
1492       return MarkAsWord32(node), VisitWord32Shr(node);
1493     case IrOpcode::kWord32Sar:
1494       return MarkAsWord32(node), VisitWord32Sar(node);
1495     case IrOpcode::kWord32Rol:
1496       return MarkAsWord32(node), VisitWord32Rol(node);
1497     case IrOpcode::kWord32Ror:
1498       return MarkAsWord32(node), VisitWord32Ror(node);
1499     case IrOpcode::kWord32Equal:
1500       return VisitWord32Equal(node);
1501     case IrOpcode::kWord32Clz:
1502       return MarkAsWord32(node), VisitWord32Clz(node);
1503     case IrOpcode::kWord32Ctz:
1504       return MarkAsWord32(node), VisitWord32Ctz(node);
1505     case IrOpcode::kWord32ReverseBits:
1506       return MarkAsWord32(node), VisitWord32ReverseBits(node);
1507     case IrOpcode::kWord32ReverseBytes:
1508       return MarkAsWord32(node), VisitWord32ReverseBytes(node);
1509     case IrOpcode::kInt32AbsWithOverflow:
1510       return MarkAsWord32(node), VisitInt32AbsWithOverflow(node);
1511     case IrOpcode::kWord32Popcnt:
1512       return MarkAsWord32(node), VisitWord32Popcnt(node);
1513     case IrOpcode::kWord64Popcnt:
1514       return MarkAsWord32(node), VisitWord64Popcnt(node);
1515     case IrOpcode::kWord32Select:
1516       return MarkAsWord32(node), VisitSelect(node);
1517     case IrOpcode::kWord64And:
1518       return MarkAsWord64(node), VisitWord64And(node);
1519     case IrOpcode::kWord64Or:
1520       return MarkAsWord64(node), VisitWord64Or(node);
1521     case IrOpcode::kWord64Xor:
1522       return MarkAsWord64(node), VisitWord64Xor(node);
1523     case IrOpcode::kWord64Shl:
1524       return MarkAsWord64(node), VisitWord64Shl(node);
1525     case IrOpcode::kWord64Shr:
1526       return MarkAsWord64(node), VisitWord64Shr(node);
1527     case IrOpcode::kWord64Sar:
1528       return MarkAsWord64(node), VisitWord64Sar(node);
1529     case IrOpcode::kWord64Rol:
1530       return MarkAsWord64(node), VisitWord64Rol(node);
1531     case IrOpcode::kWord64Ror:
1532       return MarkAsWord64(node), VisitWord64Ror(node);
1533     case IrOpcode::kWord64Clz:
1534       return MarkAsWord64(node), VisitWord64Clz(node);
1535     case IrOpcode::kWord64Ctz:
1536       return MarkAsWord64(node), VisitWord64Ctz(node);
1537     case IrOpcode::kWord64ReverseBits:
1538       return MarkAsWord64(node), VisitWord64ReverseBits(node);
1539     case IrOpcode::kWord64ReverseBytes:
1540       return MarkAsWord64(node), VisitWord64ReverseBytes(node);
1541     case IrOpcode::kSimd128ReverseBytes:
1542       return MarkAsSimd128(node), VisitSimd128ReverseBytes(node);
1543     case IrOpcode::kInt64AbsWithOverflow:
1544       return MarkAsWord64(node), VisitInt64AbsWithOverflow(node);
1545     case IrOpcode::kWord64Equal:
1546       return VisitWord64Equal(node);
1547     case IrOpcode::kWord64Select:
1548       return MarkAsWord64(node), VisitSelect(node);
1549     case IrOpcode::kInt32Add:
1550       return MarkAsWord32(node), VisitInt32Add(node);
1551     case IrOpcode::kInt32AddWithOverflow:
1552       return MarkAsWord32(node), VisitInt32AddWithOverflow(node);
1553     case IrOpcode::kInt32Sub:
1554       return MarkAsWord32(node), VisitInt32Sub(node);
1555     case IrOpcode::kInt32SubWithOverflow:
1556       return VisitInt32SubWithOverflow(node);
1557     case IrOpcode::kInt32Mul:
1558       return MarkAsWord32(node), VisitInt32Mul(node);
1559     case IrOpcode::kInt32MulWithOverflow:
1560       return MarkAsWord32(node), VisitInt32MulWithOverflow(node);
1561     case IrOpcode::kInt32MulHigh:
1562       return VisitInt32MulHigh(node);
1563     case IrOpcode::kInt32Div:
1564       return MarkAsWord32(node), VisitInt32Div(node);
1565     case IrOpcode::kInt32Mod:
1566       return MarkAsWord32(node), VisitInt32Mod(node);
1567     case IrOpcode::kInt32LessThan:
1568       return VisitInt32LessThan(node);
1569     case IrOpcode::kInt32LessThanOrEqual:
1570       return VisitInt32LessThanOrEqual(node);
1571     case IrOpcode::kUint32Div:
1572       return MarkAsWord32(node), VisitUint32Div(node);
1573     case IrOpcode::kUint32LessThan:
1574       return VisitUint32LessThan(node);
1575     case IrOpcode::kUint32LessThanOrEqual:
1576       return VisitUint32LessThanOrEqual(node);
1577     case IrOpcode::kUint32Mod:
1578       return MarkAsWord32(node), VisitUint32Mod(node);
1579     case IrOpcode::kUint32MulHigh:
1580       return VisitUint32MulHigh(node);
1581     case IrOpcode::kInt64Add:
1582       return MarkAsWord64(node), VisitInt64Add(node);
1583     case IrOpcode::kInt64AddWithOverflow:
1584       return MarkAsWord64(node), VisitInt64AddWithOverflow(node);
1585     case IrOpcode::kInt64Sub:
1586       return MarkAsWord64(node), VisitInt64Sub(node);
1587     case IrOpcode::kInt64SubWithOverflow:
1588       return MarkAsWord64(node), VisitInt64SubWithOverflow(node);
1589     case IrOpcode::kInt64Mul:
1590       return MarkAsWord64(node), VisitInt64Mul(node);
1591     case IrOpcode::kInt64Div:
1592       return MarkAsWord64(node), VisitInt64Div(node);
1593     case IrOpcode::kInt64Mod:
1594       return MarkAsWord64(node), VisitInt64Mod(node);
1595     case IrOpcode::kInt64LessThan:
1596       return VisitInt64LessThan(node);
1597     case IrOpcode::kInt64LessThanOrEqual:
1598       return VisitInt64LessThanOrEqual(node);
1599     case IrOpcode::kUint64Div:
1600       return MarkAsWord64(node), VisitUint64Div(node);
1601     case IrOpcode::kUint64LessThan:
1602       return VisitUint64LessThan(node);
1603     case IrOpcode::kUint64LessThanOrEqual:
1604       return VisitUint64LessThanOrEqual(node);
1605     case IrOpcode::kUint64Mod:
1606       return MarkAsWord64(node), VisitUint64Mod(node);
1607     case IrOpcode::kBitcastTaggedToWord:
1608     case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits:
1609       return MarkAsRepresentation(MachineType::PointerRepresentation(), node),
1610              VisitBitcastTaggedToWord(node);
1611     case IrOpcode::kBitcastWordToTagged:
1612       return MarkAsTagged(node), VisitBitcastWordToTagged(node);
1613     case IrOpcode::kBitcastWordToTaggedSigned:
1614       return MarkAsRepresentation(MachineRepresentation::kTaggedSigned, node),
1615              EmitIdentity(node);
1616     case IrOpcode::kChangeFloat32ToFloat64:
1617       return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node);
1618     case IrOpcode::kChangeInt32ToFloat64:
1619       return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node);
1620     case IrOpcode::kChangeInt64ToFloat64:
1621       return MarkAsFloat64(node), VisitChangeInt64ToFloat64(node);
1622     case IrOpcode::kChangeUint32ToFloat64:
1623       return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node);
1624     case IrOpcode::kChangeFloat64ToInt32:
1625       return MarkAsWord32(node), VisitChangeFloat64ToInt32(node);
1626     case IrOpcode::kChangeFloat64ToInt64:
1627       return MarkAsWord64(node), VisitChangeFloat64ToInt64(node);
1628     case IrOpcode::kChangeFloat64ToUint32:
1629       return MarkAsWord32(node), VisitChangeFloat64ToUint32(node);
1630     case IrOpcode::kChangeFloat64ToUint64:
1631       return MarkAsWord64(node), VisitChangeFloat64ToUint64(node);
1632     case IrOpcode::kFloat64SilenceNaN:
1633       MarkAsFloat64(node);
1634       if (CanProduceSignalingNaN(node->InputAt(0))) {
1635         return VisitFloat64SilenceNaN(node);
1636       } else {
1637         return EmitIdentity(node);
1638       }
1639     case IrOpcode::kTruncateFloat64ToInt64:
1640       return MarkAsWord64(node), VisitTruncateFloat64ToInt64(node);
1641     case IrOpcode::kTruncateFloat64ToUint32:
1642       return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node);
1643     case IrOpcode::kTruncateFloat32ToInt32:
1644       return MarkAsWord32(node), VisitTruncateFloat32ToInt32(node);
1645     case IrOpcode::kTruncateFloat32ToUint32:
1646       return MarkAsWord32(node), VisitTruncateFloat32ToUint32(node);
1647     case IrOpcode::kTryTruncateFloat32ToInt64:
1648       return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node);
1649     case IrOpcode::kTryTruncateFloat64ToInt64:
1650       return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node);
1651     case IrOpcode::kTryTruncateFloat32ToUint64:
1652       return MarkAsWord64(node), VisitTryTruncateFloat32ToUint64(node);
1653     case IrOpcode::kTryTruncateFloat64ToUint64:
1654       return MarkAsWord64(node), VisitTryTruncateFloat64ToUint64(node);
1655     case IrOpcode::kBitcastWord32ToWord64:
1656       return MarkAsWord64(node), VisitBitcastWord32ToWord64(node);
1657     case IrOpcode::kChangeInt32ToInt64:
1658       return MarkAsWord64(node), VisitChangeInt32ToInt64(node);
1659     case IrOpcode::kChangeUint32ToUint64:
1660       return MarkAsWord64(node), VisitChangeUint32ToUint64(node);
1661     case IrOpcode::kTruncateFloat64ToFloat32:
1662       return MarkAsFloat32(node), VisitTruncateFloat64ToFloat32(node);
1663     case IrOpcode::kTruncateFloat64ToWord32:
1664       return MarkAsWord32(node), VisitTruncateFloat64ToWord32(node);
1665     case IrOpcode::kTruncateInt64ToInt32:
1666       return MarkAsWord32(node), VisitTruncateInt64ToInt32(node);
1667     case IrOpcode::kRoundFloat64ToInt32:
1668       return MarkAsWord32(node), VisitRoundFloat64ToInt32(node);
1669     case IrOpcode::kRoundInt64ToFloat32:
1670       return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node);
1671     case IrOpcode::kRoundInt32ToFloat32:
1672       return MarkAsFloat32(node), VisitRoundInt32ToFloat32(node);
1673     case IrOpcode::kRoundInt64ToFloat64:
1674       return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node);
1675     case IrOpcode::kBitcastFloat32ToInt32:
1676       return MarkAsWord32(node), VisitBitcastFloat32ToInt32(node);
1677     case IrOpcode::kRoundUint32ToFloat32:
1678       return MarkAsFloat32(node), VisitRoundUint32ToFloat32(node);
1679     case IrOpcode::kRoundUint64ToFloat32:
1680       return MarkAsFloat64(node), VisitRoundUint64ToFloat32(node);
1681     case IrOpcode::kRoundUint64ToFloat64:
1682       return MarkAsFloat64(node), VisitRoundUint64ToFloat64(node);
1683     case IrOpcode::kBitcastFloat64ToInt64:
1684       return MarkAsWord64(node), VisitBitcastFloat64ToInt64(node);
1685     case IrOpcode::kBitcastInt32ToFloat32:
1686       return MarkAsFloat32(node), VisitBitcastInt32ToFloat32(node);
1687     case IrOpcode::kBitcastInt64ToFloat64:
1688       return MarkAsFloat64(node), VisitBitcastInt64ToFloat64(node);
1689     case IrOpcode::kFloat32Add:
1690       return MarkAsFloat32(node), VisitFloat32Add(node);
1691     case IrOpcode::kFloat32Sub:
1692       return MarkAsFloat32(node), VisitFloat32Sub(node);
1693     case IrOpcode::kFloat32Neg:
1694       return MarkAsFloat32(node), VisitFloat32Neg(node);
1695     case IrOpcode::kFloat32Mul:
1696       return MarkAsFloat32(node), VisitFloat32Mul(node);
1697     case IrOpcode::kFloat32Div:
1698       return MarkAsFloat32(node), VisitFloat32Div(node);
1699     case IrOpcode::kFloat32Abs:
1700       return MarkAsFloat32(node), VisitFloat32Abs(node);
1701     case IrOpcode::kFloat32Sqrt:
1702       return MarkAsFloat32(node), VisitFloat32Sqrt(node);
1703     case IrOpcode::kFloat32Equal:
1704       return VisitFloat32Equal(node);
1705     case IrOpcode::kFloat32LessThan:
1706       return VisitFloat32LessThan(node);
1707     case IrOpcode::kFloat32LessThanOrEqual:
1708       return VisitFloat32LessThanOrEqual(node);
1709     case IrOpcode::kFloat32Max:
1710       return MarkAsFloat32(node), VisitFloat32Max(node);
1711     case IrOpcode::kFloat32Min:
1712       return MarkAsFloat32(node), VisitFloat32Min(node);
1713     case IrOpcode::kFloat32Select:
1714       return MarkAsFloat32(node), VisitSelect(node);
1715     case IrOpcode::kFloat64Add:
1716       return MarkAsFloat64(node), VisitFloat64Add(node);
1717     case IrOpcode::kFloat64Sub:
1718       return MarkAsFloat64(node), VisitFloat64Sub(node);
1719     case IrOpcode::kFloat64Neg:
1720       return MarkAsFloat64(node), VisitFloat64Neg(node);
1721     case IrOpcode::kFloat64Mul:
1722       return MarkAsFloat64(node), VisitFloat64Mul(node);
1723     case IrOpcode::kFloat64Div:
1724       return MarkAsFloat64(node), VisitFloat64Div(node);
1725     case IrOpcode::kFloat64Mod:
1726       return MarkAsFloat64(node), VisitFloat64Mod(node);
1727     case IrOpcode::kFloat64Min:
1728       return MarkAsFloat64(node), VisitFloat64Min(node);
1729     case IrOpcode::kFloat64Max:
1730       return MarkAsFloat64(node), VisitFloat64Max(node);
1731     case IrOpcode::kFloat64Abs:
1732       return MarkAsFloat64(node), VisitFloat64Abs(node);
1733     case IrOpcode::kFloat64Acos:
1734       return MarkAsFloat64(node), VisitFloat64Acos(node);
1735     case IrOpcode::kFloat64Acosh:
1736       return MarkAsFloat64(node), VisitFloat64Acosh(node);
1737     case IrOpcode::kFloat64Asin:
1738       return MarkAsFloat64(node), VisitFloat64Asin(node);
1739     case IrOpcode::kFloat64Asinh:
1740       return MarkAsFloat64(node), VisitFloat64Asinh(node);
1741     case IrOpcode::kFloat64Atan:
1742       return MarkAsFloat64(node), VisitFloat64Atan(node);
1743     case IrOpcode::kFloat64Atanh:
1744       return MarkAsFloat64(node), VisitFloat64Atanh(node);
1745     case IrOpcode::kFloat64Atan2:
1746       return MarkAsFloat64(node), VisitFloat64Atan2(node);
1747     case IrOpcode::kFloat64Cbrt:
1748       return MarkAsFloat64(node), VisitFloat64Cbrt(node);
1749     case IrOpcode::kFloat64Cos:
1750       return MarkAsFloat64(node), VisitFloat64Cos(node);
1751     case IrOpcode::kFloat64Cosh:
1752       return MarkAsFloat64(node), VisitFloat64Cosh(node);
1753     case IrOpcode::kFloat64Exp:
1754       return MarkAsFloat64(node), VisitFloat64Exp(node);
1755     case IrOpcode::kFloat64Expm1:
1756       return MarkAsFloat64(node), VisitFloat64Expm1(node);
1757     case IrOpcode::kFloat64Log:
1758       return MarkAsFloat64(node), VisitFloat64Log(node);
1759     case IrOpcode::kFloat64Log1p:
1760       return MarkAsFloat64(node), VisitFloat64Log1p(node);
1761     case IrOpcode::kFloat64Log10:
1762       return MarkAsFloat64(node), VisitFloat64Log10(node);
1763     case IrOpcode::kFloat64Log2:
1764       return MarkAsFloat64(node), VisitFloat64Log2(node);
1765     case IrOpcode::kFloat64Pow:
1766       return MarkAsFloat64(node), VisitFloat64Pow(node);
1767     case IrOpcode::kFloat64Sin:
1768       return MarkAsFloat64(node), VisitFloat64Sin(node);
1769     case IrOpcode::kFloat64Sinh:
1770       return MarkAsFloat64(node), VisitFloat64Sinh(node);
1771     case IrOpcode::kFloat64Sqrt:
1772       return MarkAsFloat64(node), VisitFloat64Sqrt(node);
1773     case IrOpcode::kFloat64Tan:
1774       return MarkAsFloat64(node), VisitFloat64Tan(node);
1775     case IrOpcode::kFloat64Tanh:
1776       return MarkAsFloat64(node), VisitFloat64Tanh(node);
1777     case IrOpcode::kFloat64Equal:
1778       return VisitFloat64Equal(node);
1779     case IrOpcode::kFloat64LessThan:
1780       return VisitFloat64LessThan(node);
1781     case IrOpcode::kFloat64LessThanOrEqual:
1782       return VisitFloat64LessThanOrEqual(node);
1783     case IrOpcode::kFloat64Select:
1784       return MarkAsFloat64(node), VisitSelect(node);
1785     case IrOpcode::kFloat32RoundDown:
1786       return MarkAsFloat32(node), VisitFloat32RoundDown(node);
1787     case IrOpcode::kFloat64RoundDown:
1788       return MarkAsFloat64(node), VisitFloat64RoundDown(node);
1789     case IrOpcode::kFloat32RoundUp:
1790       return MarkAsFloat32(node), VisitFloat32RoundUp(node);
1791     case IrOpcode::kFloat64RoundUp:
1792       return MarkAsFloat64(node), VisitFloat64RoundUp(node);
1793     case IrOpcode::kFloat32RoundTruncate:
1794       return MarkAsFloat32(node), VisitFloat32RoundTruncate(node);
1795     case IrOpcode::kFloat64RoundTruncate:
1796       return MarkAsFloat64(node), VisitFloat64RoundTruncate(node);
1797     case IrOpcode::kFloat64RoundTiesAway:
1798       return MarkAsFloat64(node), VisitFloat64RoundTiesAway(node);
1799     case IrOpcode::kFloat32RoundTiesEven:
1800       return MarkAsFloat32(node), VisitFloat32RoundTiesEven(node);
1801     case IrOpcode::kFloat64RoundTiesEven:
1802       return MarkAsFloat64(node), VisitFloat64RoundTiesEven(node);
1803     case IrOpcode::kFloat64ExtractLowWord32:
1804       return MarkAsWord32(node), VisitFloat64ExtractLowWord32(node);
1805     case IrOpcode::kFloat64ExtractHighWord32:
1806       return MarkAsWord32(node), VisitFloat64ExtractHighWord32(node);
1807     case IrOpcode::kFloat64InsertLowWord32:
1808       return MarkAsFloat64(node), VisitFloat64InsertLowWord32(node);
1809     case IrOpcode::kFloat64InsertHighWord32:
1810       return MarkAsFloat64(node), VisitFloat64InsertHighWord32(node);
1811     case IrOpcode::kStackSlot:
1812       return VisitStackSlot(node);
1813     case IrOpcode::kStackPointerGreaterThan:
1814       return VisitStackPointerGreaterThan(node);
1815     case IrOpcode::kLoadStackCheckOffset:
1816       return VisitLoadStackCheckOffset(node);
1817     case IrOpcode::kLoadFramePointer:
1818       return VisitLoadFramePointer(node);
1819     case IrOpcode::kLoadParentFramePointer:
1820       return VisitLoadParentFramePointer(node);
1821     case IrOpcode::kUnalignedLoad: {
1822       LoadRepresentation type = LoadRepresentationOf(node->op());
1823       MarkAsRepresentation(type.representation(), node);
1824       return VisitUnalignedLoad(node);
1825     }
1826     case IrOpcode::kUnalignedStore:
1827       return VisitUnalignedStore(node);
1828     case IrOpcode::kInt32PairAdd:
1829       MarkAsWord32(node);
1830       MarkPairProjectionsAsWord32(node);
1831       return VisitInt32PairAdd(node);
1832     case IrOpcode::kInt32PairSub:
1833       MarkAsWord32(node);
1834       MarkPairProjectionsAsWord32(node);
1835       return VisitInt32PairSub(node);
1836     case IrOpcode::kInt32PairMul:
1837       MarkAsWord32(node);
1838       MarkPairProjectionsAsWord32(node);
1839       return VisitInt32PairMul(node);
1840     case IrOpcode::kWord32PairShl:
1841       MarkAsWord32(node);
1842       MarkPairProjectionsAsWord32(node);
1843       return VisitWord32PairShl(node);
1844     case IrOpcode::kWord32PairShr:
1845       MarkAsWord32(node);
1846       MarkPairProjectionsAsWord32(node);
1847       return VisitWord32PairShr(node);
1848     case IrOpcode::kWord32PairSar:
1849       MarkAsWord32(node);
1850       MarkPairProjectionsAsWord32(node);
1851       return VisitWord32PairSar(node);
1852     case IrOpcode::kMemoryBarrier:
1853       return VisitMemoryBarrier(node);
1854     case IrOpcode::kWord32AtomicLoad: {
1855       AtomicLoadParameters params = AtomicLoadParametersOf(node->op());
1856       LoadRepresentation type = params.representation();
1857       MarkAsRepresentation(type.representation(), node);
1858       return VisitWord32AtomicLoad(node);
1859     }
1860     case IrOpcode::kWord64AtomicLoad: {
1861       AtomicLoadParameters params = AtomicLoadParametersOf(node->op());
1862       LoadRepresentation type = params.representation();
1863       MarkAsRepresentation(type.representation(), node);
1864       return VisitWord64AtomicLoad(node);
1865     }
1866     case IrOpcode::kWord32AtomicStore:
1867       return VisitWord32AtomicStore(node);
1868     case IrOpcode::kWord64AtomicStore:
1869       return VisitWord64AtomicStore(node);
1870     case IrOpcode::kWord32AtomicPairStore:
1871       return VisitWord32AtomicPairStore(node);
1872     case IrOpcode::kWord32AtomicPairLoad: {
1873       MarkAsWord32(node);
1874       MarkPairProjectionsAsWord32(node);
1875       return VisitWord32AtomicPairLoad(node);
1876     }
1877 #define ATOMIC_CASE(name, rep)                         \
1878   case IrOpcode::k##rep##Atomic##name: {               \
1879     MachineType type = AtomicOpType(node->op());       \
1880     MarkAsRepresentation(type.representation(), node); \
1881     return Visit##rep##Atomic##name(node);             \
1882   }
1883       ATOMIC_CASE(Add, Word32)
1884       ATOMIC_CASE(Add, Word64)
1885       ATOMIC_CASE(Sub, Word32)
1886       ATOMIC_CASE(Sub, Word64)
1887       ATOMIC_CASE(And, Word32)
1888       ATOMIC_CASE(And, Word64)
1889       ATOMIC_CASE(Or, Word32)
1890       ATOMIC_CASE(Or, Word64)
1891       ATOMIC_CASE(Xor, Word32)
1892       ATOMIC_CASE(Xor, Word64)
1893       ATOMIC_CASE(Exchange, Word32)
1894       ATOMIC_CASE(Exchange, Word64)
1895       ATOMIC_CASE(CompareExchange, Word32)
1896       ATOMIC_CASE(CompareExchange, Word64)
1897 #undef ATOMIC_CASE
1898 #define ATOMIC_CASE(name)                     \
1899   case IrOpcode::kWord32AtomicPair##name: {   \
1900     MarkAsWord32(node);                       \
1901     MarkPairProjectionsAsWord32(node);        \
1902     return VisitWord32AtomicPair##name(node); \
1903   }
1904       ATOMIC_CASE(Add)
1905       ATOMIC_CASE(Sub)
1906       ATOMIC_CASE(And)
1907       ATOMIC_CASE(Or)
1908       ATOMIC_CASE(Xor)
1909       ATOMIC_CASE(Exchange)
1910       ATOMIC_CASE(CompareExchange)
1911 #undef ATOMIC_CASE
1912     case IrOpcode::kProtectedLoad: {
1913       LoadRepresentation type = LoadRepresentationOf(node->op());
1914       MarkAsRepresentation(type.representation(), node);
1915       return VisitProtectedLoad(node);
1916     }
1917     case IrOpcode::kSignExtendWord8ToInt32:
1918       return MarkAsWord32(node), VisitSignExtendWord8ToInt32(node);
1919     case IrOpcode::kSignExtendWord16ToInt32:
1920       return MarkAsWord32(node), VisitSignExtendWord16ToInt32(node);
1921     case IrOpcode::kSignExtendWord8ToInt64:
1922       return MarkAsWord64(node), VisitSignExtendWord8ToInt64(node);
1923     case IrOpcode::kSignExtendWord16ToInt64:
1924       return MarkAsWord64(node), VisitSignExtendWord16ToInt64(node);
1925     case IrOpcode::kSignExtendWord32ToInt64:
1926       return MarkAsWord64(node), VisitSignExtendWord32ToInt64(node);
1927     case IrOpcode::kUnsafePointerAdd:
1928       MarkAsRepresentation(MachineType::PointerRepresentation(), node);
1929       return VisitUnsafePointerAdd(node);
1930     case IrOpcode::kF64x2Splat:
1931       return MarkAsSimd128(node), VisitF64x2Splat(node);
1932     case IrOpcode::kF64x2ExtractLane:
1933       return MarkAsFloat64(node), VisitF64x2ExtractLane(node);
1934     case IrOpcode::kF64x2ReplaceLane:
1935       return MarkAsSimd128(node), VisitF64x2ReplaceLane(node);
1936     case IrOpcode::kF64x2Abs:
1937       return MarkAsSimd128(node), VisitF64x2Abs(node);
1938     case IrOpcode::kF64x2Neg:
1939       return MarkAsSimd128(node), VisitF64x2Neg(node);
1940     case IrOpcode::kF64x2Sqrt:
1941       return MarkAsSimd128(node), VisitF64x2Sqrt(node);
1942     case IrOpcode::kF64x2Add:
1943       return MarkAsSimd128(node), VisitF64x2Add(node);
1944     case IrOpcode::kF64x2Sub:
1945       return MarkAsSimd128(node), VisitF64x2Sub(node);
1946     case IrOpcode::kF64x2Mul:
1947       return MarkAsSimd128(node), VisitF64x2Mul(node);
1948     case IrOpcode::kF64x2Div:
1949       return MarkAsSimd128(node), VisitF64x2Div(node);
1950     case IrOpcode::kF64x2Min:
1951       return MarkAsSimd128(node), VisitF64x2Min(node);
1952     case IrOpcode::kF64x2Max:
1953       return MarkAsSimd128(node), VisitF64x2Max(node);
1954     case IrOpcode::kF64x2Eq:
1955       return MarkAsSimd128(node), VisitF64x2Eq(node);
1956     case IrOpcode::kF64x2Ne:
1957       return MarkAsSimd128(node), VisitF64x2Ne(node);
1958     case IrOpcode::kF64x2Lt:
1959       return MarkAsSimd128(node), VisitF64x2Lt(node);
1960     case IrOpcode::kF64x2Le:
1961       return MarkAsSimd128(node), VisitF64x2Le(node);
1962     case IrOpcode::kF64x2Qfma:
1963       return MarkAsSimd128(node), VisitF64x2Qfma(node);
1964     case IrOpcode::kF64x2Qfms:
1965       return MarkAsSimd128(node), VisitF64x2Qfms(node);
1966     case IrOpcode::kF64x2Pmin:
1967       return MarkAsSimd128(node), VisitF64x2Pmin(node);
1968     case IrOpcode::kF64x2Pmax:
1969       return MarkAsSimd128(node), VisitF64x2Pmax(node);
1970     case IrOpcode::kF64x2Ceil:
1971       return MarkAsSimd128(node), VisitF64x2Ceil(node);
1972     case IrOpcode::kF64x2Floor:
1973       return MarkAsSimd128(node), VisitF64x2Floor(node);
1974     case IrOpcode::kF64x2Trunc:
1975       return MarkAsSimd128(node), VisitF64x2Trunc(node);
1976     case IrOpcode::kF64x2NearestInt:
1977       return MarkAsSimd128(node), VisitF64x2NearestInt(node);
1978     case IrOpcode::kF64x2ConvertLowI32x4S:
1979       return MarkAsSimd128(node), VisitF64x2ConvertLowI32x4S(node);
1980     case IrOpcode::kF64x2ConvertLowI32x4U:
1981       return MarkAsSimd128(node), VisitF64x2ConvertLowI32x4U(node);
1982     case IrOpcode::kF64x2PromoteLowF32x4:
1983       return MarkAsSimd128(node), VisitF64x2PromoteLowF32x4(node);
1984     case IrOpcode::kF32x4Splat:
1985       return MarkAsSimd128(node), VisitF32x4Splat(node);
1986     case IrOpcode::kF32x4ExtractLane:
1987       return MarkAsFloat32(node), VisitF32x4ExtractLane(node);
1988     case IrOpcode::kF32x4ReplaceLane:
1989       return MarkAsSimd128(node), VisitF32x4ReplaceLane(node);
1990     case IrOpcode::kF32x4SConvertI32x4:
1991       return MarkAsSimd128(node), VisitF32x4SConvertI32x4(node);
1992     case IrOpcode::kF32x4UConvertI32x4:
1993       return MarkAsSimd128(node), VisitF32x4UConvertI32x4(node);
1994     case IrOpcode::kF32x4Abs:
1995       return MarkAsSimd128(node), VisitF32x4Abs(node);
1996     case IrOpcode::kF32x4Neg:
1997       return MarkAsSimd128(node), VisitF32x4Neg(node);
1998     case IrOpcode::kF32x4Sqrt:
1999       return MarkAsSimd128(node), VisitF32x4Sqrt(node);
2000     case IrOpcode::kF32x4RecipApprox:
2001       return MarkAsSimd128(node), VisitF32x4RecipApprox(node);
2002     case IrOpcode::kF32x4RecipSqrtApprox:
2003       return MarkAsSimd128(node), VisitF32x4RecipSqrtApprox(node);
2004     case IrOpcode::kF32x4Add:
2005       return MarkAsSimd128(node), VisitF32x4Add(node);
2006     case IrOpcode::kF32x4Sub:
2007       return MarkAsSimd128(node), VisitF32x4Sub(node);
2008     case IrOpcode::kF32x4Mul:
2009       return MarkAsSimd128(node), VisitF32x4Mul(node);
2010     case IrOpcode::kF32x4Div:
2011       return MarkAsSimd128(node), VisitF32x4Div(node);
2012     case IrOpcode::kF32x4Min:
2013       return MarkAsSimd128(node), VisitF32x4Min(node);
2014     case IrOpcode::kF32x4Max:
2015       return MarkAsSimd128(node), VisitF32x4Max(node);
2016     case IrOpcode::kF32x4Eq:
2017       return MarkAsSimd128(node), VisitF32x4Eq(node);
2018     case IrOpcode::kF32x4Ne:
2019       return MarkAsSimd128(node), VisitF32x4Ne(node);
2020     case IrOpcode::kF32x4Lt:
2021       return MarkAsSimd128(node), VisitF32x4Lt(node);
2022     case IrOpcode::kF32x4Le:
2023       return MarkAsSimd128(node), VisitF32x4Le(node);
2024     case IrOpcode::kF32x4Qfma:
2025       return MarkAsSimd128(node), VisitF32x4Qfma(node);
2026     case IrOpcode::kF32x4Qfms:
2027       return MarkAsSimd128(node), VisitF32x4Qfms(node);
2028     case IrOpcode::kF32x4Pmin:
2029       return MarkAsSimd128(node), VisitF32x4Pmin(node);
2030     case IrOpcode::kF32x4Pmax:
2031       return MarkAsSimd128(node), VisitF32x4Pmax(node);
2032     case IrOpcode::kF32x4Ceil:
2033       return MarkAsSimd128(node), VisitF32x4Ceil(node);
2034     case IrOpcode::kF32x4Floor:
2035       return MarkAsSimd128(node), VisitF32x4Floor(node);
2036     case IrOpcode::kF32x4Trunc:
2037       return MarkAsSimd128(node), VisitF32x4Trunc(node);
2038     case IrOpcode::kF32x4NearestInt:
2039       return MarkAsSimd128(node), VisitF32x4NearestInt(node);
2040     case IrOpcode::kF32x4DemoteF64x2Zero:
2041       return MarkAsSimd128(node), VisitF32x4DemoteF64x2Zero(node);
2042     case IrOpcode::kI64x2Splat:
2043       return MarkAsSimd128(node), VisitI64x2Splat(node);
2044     case IrOpcode::kI64x2SplatI32Pair:
2045       return MarkAsSimd128(node), VisitI64x2SplatI32Pair(node);
2046     case IrOpcode::kI64x2ExtractLane:
2047       return MarkAsWord64(node), VisitI64x2ExtractLane(node);
2048     case IrOpcode::kI64x2ReplaceLane:
2049       return MarkAsSimd128(node), VisitI64x2ReplaceLane(node);
2050     case IrOpcode::kI64x2ReplaceLaneI32Pair:
2051       return MarkAsSimd128(node), VisitI64x2ReplaceLaneI32Pair(node);
2052     case IrOpcode::kI64x2Abs:
2053       return MarkAsSimd128(node), VisitI64x2Abs(node);
2054     case IrOpcode::kI64x2Neg:
2055       return MarkAsSimd128(node), VisitI64x2Neg(node);
2056     case IrOpcode::kI64x2SConvertI32x4Low:
2057       return MarkAsSimd128(node), VisitI64x2SConvertI32x4Low(node);
2058     case IrOpcode::kI64x2SConvertI32x4High:
2059       return MarkAsSimd128(node), VisitI64x2SConvertI32x4High(node);
2060     case IrOpcode::kI64x2UConvertI32x4Low:
2061       return MarkAsSimd128(node), VisitI64x2UConvertI32x4Low(node);
2062     case IrOpcode::kI64x2UConvertI32x4High:
2063       return MarkAsSimd128(node), VisitI64x2UConvertI32x4High(node);
2064     case IrOpcode::kI64x2BitMask:
2065       return MarkAsWord32(node), VisitI64x2BitMask(node);
2066     case IrOpcode::kI64x2Shl:
2067       return MarkAsSimd128(node), VisitI64x2Shl(node);
2068     case IrOpcode::kI64x2ShrS:
2069       return MarkAsSimd128(node), VisitI64x2ShrS(node);
2070     case IrOpcode::kI64x2Add:
2071       return MarkAsSimd128(node), VisitI64x2Add(node);
2072     case IrOpcode::kI64x2Sub:
2073       return MarkAsSimd128(node), VisitI64x2Sub(node);
2074     case IrOpcode::kI64x2Mul:
2075       return MarkAsSimd128(node), VisitI64x2Mul(node);
2076     case IrOpcode::kI64x2Eq:
2077       return MarkAsSimd128(node), VisitI64x2Eq(node);
2078     case IrOpcode::kI64x2Ne:
2079       return MarkAsSimd128(node), VisitI64x2Ne(node);
2080     case IrOpcode::kI64x2GtS:
2081       return MarkAsSimd128(node), VisitI64x2GtS(node);
2082     case IrOpcode::kI64x2GeS:
2083       return MarkAsSimd128(node), VisitI64x2GeS(node);
2084     case IrOpcode::kI64x2ShrU:
2085       return MarkAsSimd128(node), VisitI64x2ShrU(node);
2086     case IrOpcode::kI64x2ExtMulLowI32x4S:
2087       return MarkAsSimd128(node), VisitI64x2ExtMulLowI32x4S(node);
2088     case IrOpcode::kI64x2ExtMulHighI32x4S:
2089       return MarkAsSimd128(node), VisitI64x2ExtMulHighI32x4S(node);
2090     case IrOpcode::kI64x2ExtMulLowI32x4U:
2091       return MarkAsSimd128(node), VisitI64x2ExtMulLowI32x4U(node);
2092     case IrOpcode::kI64x2ExtMulHighI32x4U:
2093       return MarkAsSimd128(node), VisitI64x2ExtMulHighI32x4U(node);
2094     case IrOpcode::kI32x4Splat:
2095       return MarkAsSimd128(node), VisitI32x4Splat(node);
2096     case IrOpcode::kI32x4ExtractLane:
2097       return MarkAsWord32(node), VisitI32x4ExtractLane(node);
2098     case IrOpcode::kI32x4ReplaceLane:
2099       return MarkAsSimd128(node), VisitI32x4ReplaceLane(node);
2100     case IrOpcode::kI32x4SConvertF32x4:
2101       return MarkAsSimd128(node), VisitI32x4SConvertF32x4(node);
2102     case IrOpcode::kI32x4SConvertI16x8Low:
2103       return MarkAsSimd128(node), VisitI32x4SConvertI16x8Low(node);
2104     case IrOpcode::kI32x4SConvertI16x8High:
2105       return MarkAsSimd128(node), VisitI32x4SConvertI16x8High(node);
2106     case IrOpcode::kI32x4Neg:
2107       return MarkAsSimd128(node), VisitI32x4Neg(node);
2108     case IrOpcode::kI32x4Shl:
2109       return MarkAsSimd128(node), VisitI32x4Shl(node);
2110     case IrOpcode::kI32x4ShrS:
2111       return MarkAsSimd128(node), VisitI32x4ShrS(node);
2112     case IrOpcode::kI32x4Add:
2113       return MarkAsSimd128(node), VisitI32x4Add(node);
2114     case IrOpcode::kI32x4Sub:
2115       return MarkAsSimd128(node), VisitI32x4Sub(node);
2116     case IrOpcode::kI32x4Mul:
2117       return MarkAsSimd128(node), VisitI32x4Mul(node);
2118     case IrOpcode::kI32x4MinS:
2119       return MarkAsSimd128(node), VisitI32x4MinS(node);
2120     case IrOpcode::kI32x4MaxS:
2121       return MarkAsSimd128(node), VisitI32x4MaxS(node);
2122     case IrOpcode::kI32x4Eq:
2123       return MarkAsSimd128(node), VisitI32x4Eq(node);
2124     case IrOpcode::kI32x4Ne:
2125       return MarkAsSimd128(node), VisitI32x4Ne(node);
2126     case IrOpcode::kI32x4GtS:
2127       return MarkAsSimd128(node), VisitI32x4GtS(node);
2128     case IrOpcode::kI32x4GeS:
2129       return MarkAsSimd128(node), VisitI32x4GeS(node);
2130     case IrOpcode::kI32x4UConvertF32x4:
2131       return MarkAsSimd128(node), VisitI32x4UConvertF32x4(node);
2132     case IrOpcode::kI32x4UConvertI16x8Low:
2133       return MarkAsSimd128(node), VisitI32x4UConvertI16x8Low(node);
2134     case IrOpcode::kI32x4UConvertI16x8High:
2135       return MarkAsSimd128(node), VisitI32x4UConvertI16x8High(node);
2136     case IrOpcode::kI32x4ShrU:
2137       return MarkAsSimd128(node), VisitI32x4ShrU(node);
2138     case IrOpcode::kI32x4MinU:
2139       return MarkAsSimd128(node), VisitI32x4MinU(node);
2140     case IrOpcode::kI32x4MaxU:
2141       return MarkAsSimd128(node), VisitI32x4MaxU(node);
2142     case IrOpcode::kI32x4GtU:
2143       return MarkAsSimd128(node), VisitI32x4GtU(node);
2144     case IrOpcode::kI32x4GeU:
2145       return MarkAsSimd128(node), VisitI32x4GeU(node);
2146     case IrOpcode::kI32x4Abs:
2147       return MarkAsSimd128(node), VisitI32x4Abs(node);
2148     case IrOpcode::kI32x4BitMask:
2149       return MarkAsWord32(node), VisitI32x4BitMask(node);
2150     case IrOpcode::kI32x4DotI16x8S:
2151       return MarkAsSimd128(node), VisitI32x4DotI16x8S(node);
2152     case IrOpcode::kI32x4ExtMulLowI16x8S:
2153       return MarkAsSimd128(node), VisitI32x4ExtMulLowI16x8S(node);
2154     case IrOpcode::kI32x4ExtMulHighI16x8S:
2155       return MarkAsSimd128(node), VisitI32x4ExtMulHighI16x8S(node);
2156     case IrOpcode::kI32x4ExtMulLowI16x8U:
2157       return MarkAsSimd128(node), VisitI32x4ExtMulLowI16x8U(node);
2158     case IrOpcode::kI32x4ExtMulHighI16x8U:
2159       return MarkAsSimd128(node), VisitI32x4ExtMulHighI16x8U(node);
2160     case IrOpcode::kI32x4ExtAddPairwiseI16x8S:
2161       return MarkAsSimd128(node), VisitI32x4ExtAddPairwiseI16x8S(node);
2162     case IrOpcode::kI32x4ExtAddPairwiseI16x8U:
2163       return MarkAsSimd128(node), VisitI32x4ExtAddPairwiseI16x8U(node);
2164     case IrOpcode::kI32x4TruncSatF64x2SZero:
2165       return MarkAsSimd128(node), VisitI32x4TruncSatF64x2SZero(node);
2166     case IrOpcode::kI32x4TruncSatF64x2UZero:
2167       return MarkAsSimd128(node), VisitI32x4TruncSatF64x2UZero(node);
2168     case IrOpcode::kI16x8Splat:
2169       return MarkAsSimd128(node), VisitI16x8Splat(node);
2170     case IrOpcode::kI16x8ExtractLaneU:
2171       return MarkAsWord32(node), VisitI16x8ExtractLaneU(node);
2172     case IrOpcode::kI16x8ExtractLaneS:
2173       return MarkAsWord32(node), VisitI16x8ExtractLaneS(node);
2174     case IrOpcode::kI16x8ReplaceLane:
2175       return MarkAsSimd128(node), VisitI16x8ReplaceLane(node);
2176     case IrOpcode::kI16x8SConvertI8x16Low:
2177       return MarkAsSimd128(node), VisitI16x8SConvertI8x16Low(node);
2178     case IrOpcode::kI16x8SConvertI8x16High:
2179       return MarkAsSimd128(node), VisitI16x8SConvertI8x16High(node);
2180     case IrOpcode::kI16x8Neg:
2181       return MarkAsSimd128(node), VisitI16x8Neg(node);
2182     case IrOpcode::kI16x8Shl:
2183       return MarkAsSimd128(node), VisitI16x8Shl(node);
2184     case IrOpcode::kI16x8ShrS:
2185       return MarkAsSimd128(node), VisitI16x8ShrS(node);
2186     case IrOpcode::kI16x8SConvertI32x4:
2187       return MarkAsSimd128(node), VisitI16x8SConvertI32x4(node);
2188     case IrOpcode::kI16x8Add:
2189       return MarkAsSimd128(node), VisitI16x8Add(node);
2190     case IrOpcode::kI16x8AddSatS:
2191       return MarkAsSimd128(node), VisitI16x8AddSatS(node);
2192     case IrOpcode::kI16x8Sub:
2193       return MarkAsSimd128(node), VisitI16x8Sub(node);
2194     case IrOpcode::kI16x8SubSatS:
2195       return MarkAsSimd128(node), VisitI16x8SubSatS(node);
2196     case IrOpcode::kI16x8Mul:
2197       return MarkAsSimd128(node), VisitI16x8Mul(node);
2198     case IrOpcode::kI16x8MinS:
2199       return MarkAsSimd128(node), VisitI16x8MinS(node);
2200     case IrOpcode::kI16x8MaxS:
2201       return MarkAsSimd128(node), VisitI16x8MaxS(node);
2202     case IrOpcode::kI16x8Eq:
2203       return MarkAsSimd128(node), VisitI16x8Eq(node);
2204     case IrOpcode::kI16x8Ne:
2205       return MarkAsSimd128(node), VisitI16x8Ne(node);
2206     case IrOpcode::kI16x8GtS:
2207       return MarkAsSimd128(node), VisitI16x8GtS(node);
2208     case IrOpcode::kI16x8GeS:
2209       return MarkAsSimd128(node), VisitI16x8GeS(node);
2210     case IrOpcode::kI16x8UConvertI8x16Low:
2211       return MarkAsSimd128(node), VisitI16x8UConvertI8x16Low(node);
2212     case IrOpcode::kI16x8UConvertI8x16High:
2213       return MarkAsSimd128(node), VisitI16x8UConvertI8x16High(node);
2214     case IrOpcode::kI16x8ShrU:
2215       return MarkAsSimd128(node), VisitI16x8ShrU(node);
2216     case IrOpcode::kI16x8UConvertI32x4:
2217       return MarkAsSimd128(node), VisitI16x8UConvertI32x4(node);
2218     case IrOpcode::kI16x8AddSatU:
2219       return MarkAsSimd128(node), VisitI16x8AddSatU(node);
2220     case IrOpcode::kI16x8SubSatU:
2221       return MarkAsSimd128(node), VisitI16x8SubSatU(node);
2222     case IrOpcode::kI16x8MinU:
2223       return MarkAsSimd128(node), VisitI16x8MinU(node);
2224     case IrOpcode::kI16x8MaxU:
2225       return MarkAsSimd128(node), VisitI16x8MaxU(node);
2226     case IrOpcode::kI16x8GtU:
2227       return MarkAsSimd128(node), VisitI16x8GtU(node);
2228     case IrOpcode::kI16x8GeU:
2229       return MarkAsSimd128(node), VisitI16x8GeU(node);
2230     case IrOpcode::kI16x8RoundingAverageU:
2231       return MarkAsSimd128(node), VisitI16x8RoundingAverageU(node);
2232     case IrOpcode::kI16x8Q15MulRSatS:
2233       return MarkAsSimd128(node), VisitI16x8Q15MulRSatS(node);
2234     case IrOpcode::kI16x8Abs:
2235       return MarkAsSimd128(node), VisitI16x8Abs(node);
2236     case IrOpcode::kI16x8BitMask:
2237       return MarkAsWord32(node), VisitI16x8BitMask(node);
2238     case IrOpcode::kI16x8ExtMulLowI8x16S:
2239       return MarkAsSimd128(node), VisitI16x8ExtMulLowI8x16S(node);
2240     case IrOpcode::kI16x8ExtMulHighI8x16S:
2241       return MarkAsSimd128(node), VisitI16x8ExtMulHighI8x16S(node);
2242     case IrOpcode::kI16x8ExtMulLowI8x16U:
2243       return MarkAsSimd128(node), VisitI16x8ExtMulLowI8x16U(node);
2244     case IrOpcode::kI16x8ExtMulHighI8x16U:
2245       return MarkAsSimd128(node), VisitI16x8ExtMulHighI8x16U(node);
2246     case IrOpcode::kI16x8ExtAddPairwiseI8x16S:
2247       return MarkAsSimd128(node), VisitI16x8ExtAddPairwiseI8x16S(node);
2248     case IrOpcode::kI16x8ExtAddPairwiseI8x16U:
2249       return MarkAsSimd128(node), VisitI16x8ExtAddPairwiseI8x16U(node);
2250     case IrOpcode::kI8x16Splat:
2251       return MarkAsSimd128(node), VisitI8x16Splat(node);
2252     case IrOpcode::kI8x16ExtractLaneU:
2253       return MarkAsWord32(node), VisitI8x16ExtractLaneU(node);
2254     case IrOpcode::kI8x16ExtractLaneS:
2255       return MarkAsWord32(node), VisitI8x16ExtractLaneS(node);
2256     case IrOpcode::kI8x16ReplaceLane:
2257       return MarkAsSimd128(node), VisitI8x16ReplaceLane(node);
2258     case IrOpcode::kI8x16Neg:
2259       return MarkAsSimd128(node), VisitI8x16Neg(node);
2260     case IrOpcode::kI8x16Shl:
2261       return MarkAsSimd128(node), VisitI8x16Shl(node);
2262     case IrOpcode::kI8x16ShrS:
2263       return MarkAsSimd128(node), VisitI8x16ShrS(node);
2264     case IrOpcode::kI8x16SConvertI16x8:
2265       return MarkAsSimd128(node), VisitI8x16SConvertI16x8(node);
2266     case IrOpcode::kI8x16Add:
2267       return MarkAsSimd128(node), VisitI8x16Add(node);
2268     case IrOpcode::kI8x16AddSatS:
2269       return MarkAsSimd128(node), VisitI8x16AddSatS(node);
2270     case IrOpcode::kI8x16Sub:
2271       return MarkAsSimd128(node), VisitI8x16Sub(node);
2272     case IrOpcode::kI8x16SubSatS:
2273       return MarkAsSimd128(node), VisitI8x16SubSatS(node);
2274     case IrOpcode::kI8x16MinS:
2275       return MarkAsSimd128(node), VisitI8x16MinS(node);
2276     case IrOpcode::kI8x16MaxS:
2277       return MarkAsSimd128(node), VisitI8x16MaxS(node);
2278     case IrOpcode::kI8x16Eq:
2279       return MarkAsSimd128(node), VisitI8x16Eq(node);
2280     case IrOpcode::kI8x16Ne:
2281       return MarkAsSimd128(node), VisitI8x16Ne(node);
2282     case IrOpcode::kI8x16GtS:
2283       return MarkAsSimd128(node), VisitI8x16GtS(node);
2284     case IrOpcode::kI8x16GeS:
2285       return MarkAsSimd128(node), VisitI8x16GeS(node);
2286     case IrOpcode::kI8x16ShrU:
2287       return MarkAsSimd128(node), VisitI8x16ShrU(node);
2288     case IrOpcode::kI8x16UConvertI16x8:
2289       return MarkAsSimd128(node), VisitI8x16UConvertI16x8(node);
2290     case IrOpcode::kI8x16AddSatU:
2291       return MarkAsSimd128(node), VisitI8x16AddSatU(node);
2292     case IrOpcode::kI8x16SubSatU:
2293       return MarkAsSimd128(node), VisitI8x16SubSatU(node);
2294     case IrOpcode::kI8x16MinU:
2295       return MarkAsSimd128(node), VisitI8x16MinU(node);
2296     case IrOpcode::kI8x16MaxU:
2297       return MarkAsSimd128(node), VisitI8x16MaxU(node);
2298     case IrOpcode::kI8x16GtU:
2299       return MarkAsSimd128(node), VisitI8x16GtU(node);
2300     case IrOpcode::kI8x16GeU:
2301       return MarkAsSimd128(node), VisitI8x16GeU(node);
2302     case IrOpcode::kI8x16RoundingAverageU:
2303       return MarkAsSimd128(node), VisitI8x16RoundingAverageU(node);
2304     case IrOpcode::kI8x16Popcnt:
2305       return MarkAsSimd128(node), VisitI8x16Popcnt(node);
2306     case IrOpcode::kI8x16Abs:
2307       return MarkAsSimd128(node), VisitI8x16Abs(node);
2308     case IrOpcode::kI8x16BitMask:
2309       return MarkAsWord32(node), VisitI8x16BitMask(node);
2310     case IrOpcode::kS128Const:
2311       return MarkAsSimd128(node), VisitS128Const(node);
2312     case IrOpcode::kS128Zero:
2313       return MarkAsSimd128(node), VisitS128Zero(node);
2314     case IrOpcode::kS128And:
2315       return MarkAsSimd128(node), VisitS128And(node);
2316     case IrOpcode::kS128Or:
2317       return MarkAsSimd128(node), VisitS128Or(node);
2318     case IrOpcode::kS128Xor:
2319       return MarkAsSimd128(node), VisitS128Xor(node);
2320     case IrOpcode::kS128Not:
2321       return MarkAsSimd128(node), VisitS128Not(node);
2322     case IrOpcode::kS128Select:
2323       return MarkAsSimd128(node), VisitS128Select(node);
2324     case IrOpcode::kS128AndNot:
2325       return MarkAsSimd128(node), VisitS128AndNot(node);
2326     case IrOpcode::kI8x16Swizzle:
2327       return MarkAsSimd128(node), VisitI8x16Swizzle(node);
2328     case IrOpcode::kI8x16Shuffle:
2329       return MarkAsSimd128(node), VisitI8x16Shuffle(node);
2330     case IrOpcode::kV128AnyTrue:
2331       return MarkAsWord32(node), VisitV128AnyTrue(node);
2332     case IrOpcode::kI64x2AllTrue:
2333       return MarkAsWord32(node), VisitI64x2AllTrue(node);
2334     case IrOpcode::kI32x4AllTrue:
2335       return MarkAsWord32(node), VisitI32x4AllTrue(node);
2336     case IrOpcode::kI16x8AllTrue:
2337       return MarkAsWord32(node), VisitI16x8AllTrue(node);
2338     case IrOpcode::kI8x16AllTrue:
2339       return MarkAsWord32(node), VisitI8x16AllTrue(node);
2340     case IrOpcode::kI8x16RelaxedLaneSelect:
2341       return MarkAsSimd128(node), VisitI8x16RelaxedLaneSelect(node);
2342     case IrOpcode::kI16x8RelaxedLaneSelect:
2343       return MarkAsSimd128(node), VisitI16x8RelaxedLaneSelect(node);
2344     case IrOpcode::kI32x4RelaxedLaneSelect:
2345       return MarkAsSimd128(node), VisitI32x4RelaxedLaneSelect(node);
2346     case IrOpcode::kI64x2RelaxedLaneSelect:
2347       return MarkAsSimd128(node), VisitI64x2RelaxedLaneSelect(node);
2348     case IrOpcode::kF32x4RelaxedMin:
2349       return MarkAsSimd128(node), VisitF32x4RelaxedMin(node);
2350     case IrOpcode::kF32x4RelaxedMax:
2351       return MarkAsSimd128(node), VisitF32x4RelaxedMax(node);
2352     case IrOpcode::kF64x2RelaxedMin:
2353       return MarkAsSimd128(node), VisitF64x2RelaxedMin(node);
2354     case IrOpcode::kF64x2RelaxedMax:
2355       return MarkAsSimd128(node), VisitF64x2RelaxedMax(node);
2356     case IrOpcode::kI32x4RelaxedTruncF64x2SZero:
2357       return MarkAsSimd128(node), VisitI32x4RelaxedTruncF64x2SZero(node);
2358     case IrOpcode::kI32x4RelaxedTruncF64x2UZero:
2359       return MarkAsSimd128(node), VisitI32x4RelaxedTruncF64x2UZero(node);
2360     case IrOpcode::kI32x4RelaxedTruncF32x4S:
2361       return MarkAsSimd128(node), VisitI32x4RelaxedTruncF32x4S(node);
2362     case IrOpcode::kI32x4RelaxedTruncF32x4U:
2363       return MarkAsSimd128(node), VisitI32x4RelaxedTruncF32x4U(node);
2364     default:
2365       FATAL("Unexpected operator #%d:%s @ node #%d", node->opcode(),
2366             node->op()->mnemonic(), node->id());
2367   }
2368 }
2369 
VisitStackPointerGreaterThan(Node * node)2370 void InstructionSelector::VisitStackPointerGreaterThan(Node* node) {
2371   FlagsContinuation cont =
2372       FlagsContinuation::ForSet(kStackPointerGreaterThanCondition, node);
2373   VisitStackPointerGreaterThan(node, &cont);
2374 }
2375 
VisitLoadStackCheckOffset(Node * node)2376 void InstructionSelector::VisitLoadStackCheckOffset(Node* node) {
2377   OperandGenerator g(this);
2378   Emit(kArchStackCheckOffset, g.DefineAsRegister(node));
2379 }
2380 
VisitLoadFramePointer(Node * node)2381 void InstructionSelector::VisitLoadFramePointer(Node* node) {
2382   OperandGenerator g(this);
2383   Emit(kArchFramePointer, g.DefineAsRegister(node));
2384 }
2385 
VisitLoadParentFramePointer(Node * node)2386 void InstructionSelector::VisitLoadParentFramePointer(Node* node) {
2387   OperandGenerator g(this);
2388   Emit(kArchParentFramePointer, g.DefineAsRegister(node));
2389 }
2390 
VisitFloat64Acos(Node * node)2391 void InstructionSelector::VisitFloat64Acos(Node* node) {
2392   VisitFloat64Ieee754Unop(node, kIeee754Float64Acos);
2393 }
2394 
VisitFloat64Acosh(Node * node)2395 void InstructionSelector::VisitFloat64Acosh(Node* node) {
2396   VisitFloat64Ieee754Unop(node, kIeee754Float64Acosh);
2397 }
2398 
VisitFloat64Asin(Node * node)2399 void InstructionSelector::VisitFloat64Asin(Node* node) {
2400   VisitFloat64Ieee754Unop(node, kIeee754Float64Asin);
2401 }
2402 
VisitFloat64Asinh(Node * node)2403 void InstructionSelector::VisitFloat64Asinh(Node* node) {
2404   VisitFloat64Ieee754Unop(node, kIeee754Float64Asinh);
2405 }
2406 
VisitFloat64Atan(Node * node)2407 void InstructionSelector::VisitFloat64Atan(Node* node) {
2408   VisitFloat64Ieee754Unop(node, kIeee754Float64Atan);
2409 }
2410 
VisitFloat64Atanh(Node * node)2411 void InstructionSelector::VisitFloat64Atanh(Node* node) {
2412   VisitFloat64Ieee754Unop(node, kIeee754Float64Atanh);
2413 }
2414 
VisitFloat64Atan2(Node * node)2415 void InstructionSelector::VisitFloat64Atan2(Node* node) {
2416   VisitFloat64Ieee754Binop(node, kIeee754Float64Atan2);
2417 }
2418 
VisitFloat64Cbrt(Node * node)2419 void InstructionSelector::VisitFloat64Cbrt(Node* node) {
2420   VisitFloat64Ieee754Unop(node, kIeee754Float64Cbrt);
2421 }
2422 
VisitFloat64Cos(Node * node)2423 void InstructionSelector::VisitFloat64Cos(Node* node) {
2424   VisitFloat64Ieee754Unop(node, kIeee754Float64Cos);
2425 }
2426 
VisitFloat64Cosh(Node * node)2427 void InstructionSelector::VisitFloat64Cosh(Node* node) {
2428   VisitFloat64Ieee754Unop(node, kIeee754Float64Cosh);
2429 }
2430 
VisitFloat64Exp(Node * node)2431 void InstructionSelector::VisitFloat64Exp(Node* node) {
2432   VisitFloat64Ieee754Unop(node, kIeee754Float64Exp);
2433 }
2434 
VisitFloat64Expm1(Node * node)2435 void InstructionSelector::VisitFloat64Expm1(Node* node) {
2436   VisitFloat64Ieee754Unop(node, kIeee754Float64Expm1);
2437 }
2438 
VisitFloat64Log(Node * node)2439 void InstructionSelector::VisitFloat64Log(Node* node) {
2440   VisitFloat64Ieee754Unop(node, kIeee754Float64Log);
2441 }
2442 
VisitFloat64Log1p(Node * node)2443 void InstructionSelector::VisitFloat64Log1p(Node* node) {
2444   VisitFloat64Ieee754Unop(node, kIeee754Float64Log1p);
2445 }
2446 
VisitFloat64Log2(Node * node)2447 void InstructionSelector::VisitFloat64Log2(Node* node) {
2448   VisitFloat64Ieee754Unop(node, kIeee754Float64Log2);
2449 }
2450 
VisitFloat64Log10(Node * node)2451 void InstructionSelector::VisitFloat64Log10(Node* node) {
2452   VisitFloat64Ieee754Unop(node, kIeee754Float64Log10);
2453 }
2454 
VisitFloat64Pow(Node * node)2455 void InstructionSelector::VisitFloat64Pow(Node* node) {
2456   VisitFloat64Ieee754Binop(node, kIeee754Float64Pow);
2457 }
2458 
VisitFloat64Sin(Node * node)2459 void InstructionSelector::VisitFloat64Sin(Node* node) {
2460   VisitFloat64Ieee754Unop(node, kIeee754Float64Sin);
2461 }
2462 
VisitFloat64Sinh(Node * node)2463 void InstructionSelector::VisitFloat64Sinh(Node* node) {
2464   VisitFloat64Ieee754Unop(node, kIeee754Float64Sinh);
2465 }
2466 
VisitFloat64Tan(Node * node)2467 void InstructionSelector::VisitFloat64Tan(Node* node) {
2468   VisitFloat64Ieee754Unop(node, kIeee754Float64Tan);
2469 }
2470 
VisitFloat64Tanh(Node * node)2471 void InstructionSelector::VisitFloat64Tanh(Node* node) {
2472   VisitFloat64Ieee754Unop(node, kIeee754Float64Tanh);
2473 }
2474 
EmitTableSwitch(const SwitchInfo & sw,InstructionOperand const & index_operand)2475 void InstructionSelector::EmitTableSwitch(
2476     const SwitchInfo& sw, InstructionOperand const& index_operand) {
2477   OperandGenerator g(this);
2478   size_t input_count = 2 + sw.value_range();
2479   DCHECK_LE(sw.value_range(), std::numeric_limits<size_t>::max() - 2);
2480   auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
2481   inputs[0] = index_operand;
2482   InstructionOperand default_operand = g.Label(sw.default_branch());
2483   std::fill(&inputs[1], &inputs[input_count], default_operand);
2484   for (const CaseInfo& c : sw.CasesUnsorted()) {
2485     size_t value = c.value - sw.min_value();
2486     DCHECK_LE(0u, value);
2487     DCHECK_LT(value + 2, input_count);
2488     inputs[value + 2] = g.Label(c.branch);
2489   }
2490   Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
2491 }
2492 
EmitBinarySearchSwitch(const SwitchInfo & sw,InstructionOperand const & value_operand)2493 void InstructionSelector::EmitBinarySearchSwitch(
2494     const SwitchInfo& sw, InstructionOperand const& value_operand) {
2495   OperandGenerator g(this);
2496   size_t input_count = 2 + sw.case_count() * 2;
2497   DCHECK_LE(sw.case_count(), (std::numeric_limits<size_t>::max() - 2) / 2);
2498   auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
2499   inputs[0] = value_operand;
2500   inputs[1] = g.Label(sw.default_branch());
2501   std::vector<CaseInfo> cases = sw.CasesSortedByValue();
2502   for (size_t index = 0; index < cases.size(); ++index) {
2503     const CaseInfo& c = cases[index];
2504     inputs[index * 2 + 2 + 0] = g.TempImmediate(c.value);
2505     inputs[index * 2 + 2 + 1] = g.Label(c.branch);
2506   }
2507   Emit(kArchBinarySearchSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
2508 }
2509 
VisitBitcastTaggedToWord(Node * node)2510 void InstructionSelector::VisitBitcastTaggedToWord(Node* node) {
2511   EmitIdentity(node);
2512 }
2513 
VisitBitcastWordToTagged(Node * node)2514 void InstructionSelector::VisitBitcastWordToTagged(Node* node) {
2515   OperandGenerator g(this);
2516   Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(node->InputAt(0)));
2517 }
2518 
2519 // 32 bit targets do not implement the following instructions.
2520 #if V8_TARGET_ARCH_32_BIT
2521 
VisitWord64And(Node * node)2522 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
2523 
VisitWord64Or(Node * node)2524 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); }
2525 
VisitWord64Xor(Node * node)2526 void InstructionSelector::VisitWord64Xor(Node* node) { UNIMPLEMENTED(); }
2527 
VisitWord64Shl(Node * node)2528 void InstructionSelector::VisitWord64Shl(Node* node) { UNIMPLEMENTED(); }
2529 
VisitWord64Shr(Node * node)2530 void InstructionSelector::VisitWord64Shr(Node* node) { UNIMPLEMENTED(); }
2531 
VisitWord64Sar(Node * node)2532 void InstructionSelector::VisitWord64Sar(Node* node) { UNIMPLEMENTED(); }
2533 
VisitWord64Rol(Node * node)2534 void InstructionSelector::VisitWord64Rol(Node* node) { UNIMPLEMENTED(); }
2535 
VisitWord64Ror(Node * node)2536 void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); }
2537 
VisitWord64Clz(Node * node)2538 void InstructionSelector::VisitWord64Clz(Node* node) { UNIMPLEMENTED(); }
2539 
VisitWord64Ctz(Node * node)2540 void InstructionSelector::VisitWord64Ctz(Node* node) { UNIMPLEMENTED(); }
2541 
VisitWord64ReverseBits(Node * node)2542 void InstructionSelector::VisitWord64ReverseBits(Node* node) {
2543   UNIMPLEMENTED();
2544 }
2545 
VisitWord64Popcnt(Node * node)2546 void InstructionSelector::VisitWord64Popcnt(Node* node) { UNIMPLEMENTED(); }
2547 
VisitWord64Equal(Node * node)2548 void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); }
2549 
VisitInt64Add(Node * node)2550 void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
2551 
VisitInt64AddWithOverflow(Node * node)2552 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
2553   UNIMPLEMENTED();
2554 }
2555 
VisitInt64Sub(Node * node)2556 void InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); }
2557 
VisitInt64SubWithOverflow(Node * node)2558 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
2559   UNIMPLEMENTED();
2560 }
2561 
VisitInt64Mul(Node * node)2562 void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); }
2563 
VisitInt64Div(Node * node)2564 void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); }
2565 
VisitInt64LessThan(Node * node)2566 void InstructionSelector::VisitInt64LessThan(Node* node) { UNIMPLEMENTED(); }
2567 
VisitInt64LessThanOrEqual(Node * node)2568 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
2569   UNIMPLEMENTED();
2570 }
2571 
VisitUint64Div(Node * node)2572 void InstructionSelector::VisitUint64Div(Node* node) { UNIMPLEMENTED(); }
2573 
VisitInt64Mod(Node * node)2574 void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
2575 
VisitUint64LessThan(Node * node)2576 void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); }
2577 
VisitUint64LessThanOrEqual(Node * node)2578 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
2579   UNIMPLEMENTED();
2580 }
2581 
VisitUint64Mod(Node * node)2582 void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); }
2583 
VisitBitcastWord32ToWord64(Node * node)2584 void InstructionSelector::VisitBitcastWord32ToWord64(Node* node) {
2585   UNIMPLEMENTED();
2586 }
2587 
VisitChangeInt32ToInt64(Node * node)2588 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
2589   UNIMPLEMENTED();
2590 }
2591 
VisitChangeInt64ToFloat64(Node * node)2592 void InstructionSelector::VisitChangeInt64ToFloat64(Node* node) {
2593   UNIMPLEMENTED();
2594 }
2595 
VisitChangeUint32ToUint64(Node * node)2596 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
2597   UNIMPLEMENTED();
2598 }
2599 
VisitChangeFloat64ToInt64(Node * node)2600 void InstructionSelector::VisitChangeFloat64ToInt64(Node* node) {
2601   UNIMPLEMENTED();
2602 }
2603 
VisitChangeFloat64ToUint64(Node * node)2604 void InstructionSelector::VisitChangeFloat64ToUint64(Node* node) {
2605   UNIMPLEMENTED();
2606 }
2607 
VisitTruncateFloat64ToInt64(Node * node)2608 void InstructionSelector::VisitTruncateFloat64ToInt64(Node* node) {
2609   UNIMPLEMENTED();
2610 }
2611 
VisitTryTruncateFloat32ToInt64(Node * node)2612 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
2613   UNIMPLEMENTED();
2614 }
2615 
VisitTryTruncateFloat64ToInt64(Node * node)2616 void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
2617   UNIMPLEMENTED();
2618 }
2619 
VisitTryTruncateFloat32ToUint64(Node * node)2620 void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
2621   UNIMPLEMENTED();
2622 }
2623 
VisitTryTruncateFloat64ToUint64(Node * node)2624 void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
2625   UNIMPLEMENTED();
2626 }
2627 
VisitTruncateInt64ToInt32(Node * node)2628 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
2629   UNIMPLEMENTED();
2630 }
2631 
VisitRoundInt64ToFloat32(Node * node)2632 void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
2633   UNIMPLEMENTED();
2634 }
2635 
VisitRoundInt64ToFloat64(Node * node)2636 void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
2637   UNIMPLEMENTED();
2638 }
2639 
VisitRoundUint64ToFloat32(Node * node)2640 void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
2641   UNIMPLEMENTED();
2642 }
2643 
VisitRoundUint64ToFloat64(Node * node)2644 void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
2645   UNIMPLEMENTED();
2646 }
2647 
VisitBitcastFloat64ToInt64(Node * node)2648 void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
2649   UNIMPLEMENTED();
2650 }
2651 
VisitBitcastInt64ToFloat64(Node * node)2652 void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
2653   UNIMPLEMENTED();
2654 }
2655 
VisitSignExtendWord8ToInt64(Node * node)2656 void InstructionSelector::VisitSignExtendWord8ToInt64(Node* node) {
2657   UNIMPLEMENTED();
2658 }
2659 
VisitSignExtendWord16ToInt64(Node * node)2660 void InstructionSelector::VisitSignExtendWord16ToInt64(Node* node) {
2661   UNIMPLEMENTED();
2662 }
2663 
VisitSignExtendWord32ToInt64(Node * node)2664 void InstructionSelector::VisitSignExtendWord32ToInt64(Node* node) {
2665   UNIMPLEMENTED();
2666 }
2667 #endif  // V8_TARGET_ARCH_32_BIT
2668 
2669 // 64 bit targets do not implement the following instructions.
2670 #if V8_TARGET_ARCH_64_BIT
VisitInt32PairAdd(Node * node)2671 void InstructionSelector::VisitInt32PairAdd(Node* node) { UNIMPLEMENTED(); }
2672 
VisitInt32PairSub(Node * node)2673 void InstructionSelector::VisitInt32PairSub(Node* node) { UNIMPLEMENTED(); }
2674 
VisitInt32PairMul(Node * node)2675 void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); }
2676 
VisitWord32PairShl(Node * node)2677 void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); }
2678 
VisitWord32PairShr(Node * node)2679 void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); }
2680 
VisitWord32PairSar(Node * node)2681 void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); }
2682 #endif  // V8_TARGET_ARCH_64_BIT
2683 
2684 #if !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS
VisitWord32AtomicPairLoad(Node * node)2685 void InstructionSelector::VisitWord32AtomicPairLoad(Node* node) {
2686   UNIMPLEMENTED();
2687 }
2688 
VisitWord32AtomicPairStore(Node * node)2689 void InstructionSelector::VisitWord32AtomicPairStore(Node* node) {
2690   UNIMPLEMENTED();
2691 }
2692 
VisitWord32AtomicPairAdd(Node * node)2693 void InstructionSelector::VisitWord32AtomicPairAdd(Node* node) {
2694   UNIMPLEMENTED();
2695 }
2696 
VisitWord32AtomicPairSub(Node * node)2697 void InstructionSelector::VisitWord32AtomicPairSub(Node* node) {
2698   UNIMPLEMENTED();
2699 }
2700 
VisitWord32AtomicPairAnd(Node * node)2701 void InstructionSelector::VisitWord32AtomicPairAnd(Node* node) {
2702   UNIMPLEMENTED();
2703 }
2704 
VisitWord32AtomicPairOr(Node * node)2705 void InstructionSelector::VisitWord32AtomicPairOr(Node* node) {
2706   UNIMPLEMENTED();
2707 }
2708 
VisitWord32AtomicPairXor(Node * node)2709 void InstructionSelector::VisitWord32AtomicPairXor(Node* node) {
2710   UNIMPLEMENTED();
2711 }
2712 
VisitWord32AtomicPairExchange(Node * node)2713 void InstructionSelector::VisitWord32AtomicPairExchange(Node* node) {
2714   UNIMPLEMENTED();
2715 }
2716 
VisitWord32AtomicPairCompareExchange(Node * node)2717 void InstructionSelector::VisitWord32AtomicPairCompareExchange(Node* node) {
2718   UNIMPLEMENTED();
2719 }
2720 #endif  // !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS
2721 
2722 #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS64 && \
2723     !V8_TARGET_ARCH_S390 && !V8_TARGET_ARCH_PPC64 &&                          \
2724     !V8_TARGET_ARCH_RISCV64 && !V8_TARGET_ARCH_LOONG64
VisitWord64AtomicLoad(Node * node)2725 void InstructionSelector::VisitWord64AtomicLoad(Node* node) { UNIMPLEMENTED(); }
2726 
VisitWord64AtomicStore(Node * node)2727 void InstructionSelector::VisitWord64AtomicStore(Node* node) {
2728   UNIMPLEMENTED();
2729 }
2730 
VisitWord64AtomicAdd(Node * node)2731 void InstructionSelector::VisitWord64AtomicAdd(Node* node) { UNIMPLEMENTED(); }
2732 
VisitWord64AtomicSub(Node * node)2733 void InstructionSelector::VisitWord64AtomicSub(Node* node) { UNIMPLEMENTED(); }
2734 
VisitWord64AtomicAnd(Node * node)2735 void InstructionSelector::VisitWord64AtomicAnd(Node* node) { UNIMPLEMENTED(); }
2736 
VisitWord64AtomicOr(Node * node)2737 void InstructionSelector::VisitWord64AtomicOr(Node* node) { UNIMPLEMENTED(); }
2738 
VisitWord64AtomicXor(Node * node)2739 void InstructionSelector::VisitWord64AtomicXor(Node* node) { UNIMPLEMENTED(); }
2740 
VisitWord64AtomicExchange(Node * node)2741 void InstructionSelector::VisitWord64AtomicExchange(Node* node) {
2742   UNIMPLEMENTED();
2743 }
2744 
VisitWord64AtomicCompareExchange(Node * node)2745 void InstructionSelector::VisitWord64AtomicCompareExchange(Node* node) {
2746   UNIMPLEMENTED();
2747 }
2748 #endif  // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_PPC64
2749         // !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_S390 &&
2750         // !V8_TARGET_ARCH_RISCV64 && !V8_TARGET_ARCH_LOONG64
2751 
2752 #if !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM
2753 // This is only needed on 32-bit to split the 64-bit value into two operands.
VisitI64x2SplatI32Pair(Node * node)2754 void InstructionSelector::VisitI64x2SplatI32Pair(Node* node) {
2755   UNIMPLEMENTED();
2756 }
VisitI64x2ReplaceLaneI32Pair(Node * node)2757 void InstructionSelector::VisitI64x2ReplaceLaneI32Pair(Node* node) {
2758   UNIMPLEMENTED();
2759 }
2760 #endif  // !V8_TARGET_ARCH_IA32
2761 
2762 #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X && !V8_TARGET_ARCH_PPC64
2763 #if !V8_TARGET_ARCH_ARM64
2764 #if !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_LOONG64 && !V8_TARGET_ARCH_RISCV64
VisitI64x2Splat(Node * node)2765 void InstructionSelector::VisitI64x2Splat(Node* node) { UNIMPLEMENTED(); }
VisitI64x2ExtractLane(Node * node)2766 void InstructionSelector::VisitI64x2ExtractLane(Node* node) { UNIMPLEMENTED(); }
VisitI64x2ReplaceLane(Node * node)2767 void InstructionSelector::VisitI64x2ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2768 #endif  // !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_LOONG64 &&
2769         // !V8_TARGET_ARCH_RISCV64
2770 #endif  // !V8_TARGET_ARCH_ARM64
2771 #endif  // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X && !V8_TARGET_ARCH_PPC64
2772 
2773 #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X && !V8_TARGET_ARCH_PPC64 && \
2774     !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_RISCV64
VisitF64x2Qfma(Node * node)2775 void InstructionSelector::VisitF64x2Qfma(Node* node) { UNIMPLEMENTED(); }
VisitF64x2Qfms(Node * node)2776 void InstructionSelector::VisitF64x2Qfms(Node* node) { UNIMPLEMENTED(); }
VisitF32x4Qfma(Node * node)2777 void InstructionSelector::VisitF32x4Qfma(Node* node) { UNIMPLEMENTED(); }
VisitF32x4Qfms(Node * node)2778 void InstructionSelector::VisitF32x4Qfms(Node* node) { UNIMPLEMENTED(); }
2779 #endif  // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X && !V8_TARGET_ARCH_PPC64
2780         // && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_IA32 &&
2781         // !V8_TARGET_ARCH_RISCV64
2782 
2783 #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM64 && \
2784     !V8_TARGET_ARCH_RISCV64 && !V8_TARGET_ARCH_ARM
VisitI8x16RelaxedLaneSelect(Node * node)2785 void InstructionSelector::VisitI8x16RelaxedLaneSelect(Node* node) {
2786   UNIMPLEMENTED();
2787 }
VisitI16x8RelaxedLaneSelect(Node * node)2788 void InstructionSelector::VisitI16x8RelaxedLaneSelect(Node* node) {
2789   UNIMPLEMENTED();
2790 }
VisitI32x4RelaxedLaneSelect(Node * node)2791 void InstructionSelector::VisitI32x4RelaxedLaneSelect(Node* node) {
2792   UNIMPLEMENTED();
2793 }
VisitI64x2RelaxedLaneSelect(Node * node)2794 void InstructionSelector::VisitI64x2RelaxedLaneSelect(Node* node) {
2795   UNIMPLEMENTED();
2796 }
VisitF32x4RelaxedMin(Node * node)2797 void InstructionSelector::VisitF32x4RelaxedMin(Node* node) { UNIMPLEMENTED(); }
VisitF32x4RelaxedMax(Node * node)2798 void InstructionSelector::VisitF32x4RelaxedMax(Node* node) { UNIMPLEMENTED(); }
VisitF64x2RelaxedMin(Node * node)2799 void InstructionSelector::VisitF64x2RelaxedMin(Node* node) { UNIMPLEMENTED(); }
VisitF64x2RelaxedMax(Node * node)2800 void InstructionSelector::VisitF64x2RelaxedMax(Node* node) { UNIMPLEMENTED(); }
VisitI32x4RelaxedTruncF64x2SZero(Node * node)2801 void InstructionSelector::VisitI32x4RelaxedTruncF64x2SZero(Node* node) {
2802   UNIMPLEMENTED();
2803 }
VisitI32x4RelaxedTruncF64x2UZero(Node * node)2804 void InstructionSelector::VisitI32x4RelaxedTruncF64x2UZero(Node* node) {
2805   UNIMPLEMENTED();
2806 }
VisitI32x4RelaxedTruncF32x4S(Node * node)2807 void InstructionSelector::VisitI32x4RelaxedTruncF32x4S(Node* node) {
2808   UNIMPLEMENTED();
2809 }
VisitI32x4RelaxedTruncF32x4U(Node * node)2810 void InstructionSelector::VisitI32x4RelaxedTruncF32x4U(Node* node) {
2811   UNIMPLEMENTED();
2812 }
2813 #endif  // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM64
2814         // && !V8_TARGET_ARCH_RISCV64 && !V8_TARGET_ARM
2815 
2816 #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM64 && \
2817     !V8_TARGET_ARCH_RISCV64
2818 #endif  // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM64
2819         // && !V8_TARGET_ARCH_RISCV64
2820 
VisitFinishRegion(Node * node)2821 void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); }
2822 
VisitParameter(Node * node)2823 void InstructionSelector::VisitParameter(Node* node) {
2824   OperandGenerator g(this);
2825   int index = ParameterIndexOf(node->op());
2826   InstructionOperand op =
2827       linkage()->ParameterHasSecondaryLocation(index)
2828           ? g.DefineAsDualLocation(
2829                 node, linkage()->GetParameterLocation(index),
2830                 linkage()->GetParameterSecondaryLocation(index))
2831           : g.DefineAsLocation(node, linkage()->GetParameterLocation(index));
2832 
2833   Emit(kArchNop, op);
2834 }
2835 
2836 namespace {
2837 
ExceptionLocation()2838 LinkageLocation ExceptionLocation() {
2839   return LinkageLocation::ForRegister(kReturnRegister0.code(),
2840                                       MachineType::TaggedPointer());
2841 }
2842 
EncodeCallDescriptorFlags(InstructionCode opcode,CallDescriptor::Flags flags)2843 constexpr InstructionCode EncodeCallDescriptorFlags(
2844     InstructionCode opcode, CallDescriptor::Flags flags) {
2845   // Note: Not all bits of `flags` are preserved.
2846   STATIC_ASSERT(CallDescriptor::kFlagsBitsEncodedInInstructionCode ==
2847                 MiscField::kSize);
2848   DCHECK(Instruction::IsCallWithDescriptorFlags(opcode));
2849   return opcode | MiscField::encode(flags & MiscField::kMax);
2850 }
2851 
2852 }  // namespace
2853 
VisitIfException(Node * node)2854 void InstructionSelector::VisitIfException(Node* node) {
2855   OperandGenerator g(this);
2856   DCHECK_EQ(IrOpcode::kCall, node->InputAt(1)->opcode());
2857   Emit(kArchNop, g.DefineAsLocation(node, ExceptionLocation()));
2858 }
2859 
VisitOsrValue(Node * node)2860 void InstructionSelector::VisitOsrValue(Node* node) {
2861   OperandGenerator g(this);
2862   int index = OsrValueIndexOf(node->op());
2863   Emit(kArchNop,
2864        g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index)));
2865 }
2866 
VisitPhi(Node * node)2867 void InstructionSelector::VisitPhi(Node* node) {
2868   const int input_count = node->op()->ValueInputCount();
2869   DCHECK_EQ(input_count, current_block_->PredecessorCount());
2870   PhiInstruction* phi = instruction_zone()->New<PhiInstruction>(
2871       instruction_zone(), GetVirtualRegister(node),
2872       static_cast<size_t>(input_count));
2873   sequence()
2874       ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number()))
2875       ->AddPhi(phi);
2876   for (int i = 0; i < input_count; ++i) {
2877     Node* const input = node->InputAt(i);
2878     MarkAsUsed(input);
2879     phi->SetInput(static_cast<size_t>(i), GetVirtualRegister(input));
2880   }
2881 }
2882 
VisitProjection(Node * node)2883 void InstructionSelector::VisitProjection(Node* node) {
2884   OperandGenerator g(this);
2885   Node* value = node->InputAt(0);
2886   switch (value->opcode()) {
2887     case IrOpcode::kInt32AddWithOverflow:
2888     case IrOpcode::kInt32SubWithOverflow:
2889     case IrOpcode::kInt32MulWithOverflow:
2890     case IrOpcode::kInt64AddWithOverflow:
2891     case IrOpcode::kInt64SubWithOverflow:
2892     case IrOpcode::kTryTruncateFloat32ToInt64:
2893     case IrOpcode::kTryTruncateFloat64ToInt64:
2894     case IrOpcode::kTryTruncateFloat32ToUint64:
2895     case IrOpcode::kTryTruncateFloat64ToUint64:
2896     case IrOpcode::kInt32PairAdd:
2897     case IrOpcode::kInt32PairSub:
2898     case IrOpcode::kInt32PairMul:
2899     case IrOpcode::kWord32PairShl:
2900     case IrOpcode::kWord32PairShr:
2901     case IrOpcode::kWord32PairSar:
2902     case IrOpcode::kInt32AbsWithOverflow:
2903     case IrOpcode::kInt64AbsWithOverflow:
2904       if (ProjectionIndexOf(node->op()) == 0u) {
2905         Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
2906       } else {
2907         DCHECK_EQ(1u, ProjectionIndexOf(node->op()));
2908         MarkAsUsed(value);
2909       }
2910       break;
2911     default:
2912       break;
2913   }
2914 }
2915 
VisitConstant(Node * node)2916 void InstructionSelector::VisitConstant(Node* node) {
2917   // We must emit a NOP here because every live range needs a defining
2918   // instruction in the register allocator.
2919   OperandGenerator g(this);
2920   Emit(kArchNop, g.DefineAsConstant(node));
2921 }
2922 
UpdateMaxPushedArgumentCount(size_t count)2923 void InstructionSelector::UpdateMaxPushedArgumentCount(size_t count) {
2924   *max_pushed_argument_count_ = std::max(count, *max_pushed_argument_count_);
2925 }
2926 
VisitCall(Node * node,BasicBlock * handler)2927 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
2928   OperandGenerator g(this);
2929   auto call_descriptor = CallDescriptorOf(node->op());
2930   SaveFPRegsMode mode = call_descriptor->NeedsCallerSavedFPRegisters()
2931                             ? SaveFPRegsMode::kSave
2932                             : SaveFPRegsMode::kIgnore;
2933 
2934   if (call_descriptor->NeedsCallerSavedRegisters()) {
2935     Emit(kArchSaveCallerRegisters | MiscField::encode(static_cast<int>(mode)),
2936          g.NoOutput());
2937   }
2938 
2939   FrameStateDescriptor* frame_state_descriptor = nullptr;
2940   if (call_descriptor->NeedsFrameState()) {
2941     frame_state_descriptor = GetFrameStateDescriptor(FrameState{
2942         node->InputAt(static_cast<int>(call_descriptor->InputCount()))});
2943   }
2944 
2945   CallBuffer buffer(zone(), call_descriptor, frame_state_descriptor);
2946   CallDescriptor::Flags flags = call_descriptor->flags();
2947 
2948   // Compute InstructionOperands for inputs and outputs.
2949   // TODO(turbofan): on some architectures it's probably better to use
2950   // the code object in a register if there are multiple uses of it.
2951   // Improve constant pool and the heuristics in the register allocator
2952   // for where to emit constants.
2953   CallBufferFlags call_buffer_flags(kCallCodeImmediate | kCallAddressImmediate);
2954   InitializeCallBuffer(node, &buffer, call_buffer_flags);
2955 
2956   EmitPrepareArguments(&buffer.pushed_nodes, call_descriptor, node);
2957   UpdateMaxPushedArgumentCount(buffer.pushed_nodes.size());
2958 
2959   // Pass label of exception handler block.
2960   if (handler) {
2961     DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode());
2962     flags |= CallDescriptor::kHasExceptionHandler;
2963     buffer.instruction_args.push_back(g.Label(handler));
2964   }
2965 
2966   // Select the appropriate opcode based on the call type.
2967   InstructionCode opcode;
2968   switch (call_descriptor->kind()) {
2969     case CallDescriptor::kCallAddress: {
2970       int gp_param_count =
2971           static_cast<int>(call_descriptor->GPParameterCount());
2972       int fp_param_count =
2973           static_cast<int>(call_descriptor->FPParameterCount());
2974 #if ABI_USES_FUNCTION_DESCRIPTORS
2975       // Highest fp_param_count bit is used on AIX to indicate if a CFunction
2976       // call has function descriptor or not.
2977       STATIC_ASSERT(FPParamField::kSize == kHasFunctionDescriptorBitShift + 1);
2978       if (!call_descriptor->NoFunctionDescriptor()) {
2979         fp_param_count |= 1 << kHasFunctionDescriptorBitShift;
2980       }
2981 #endif
2982       opcode = kArchCallCFunction | ParamField::encode(gp_param_count) |
2983                FPParamField::encode(fp_param_count);
2984       break;
2985     }
2986     case CallDescriptor::kCallCodeObject:
2987       opcode = EncodeCallDescriptorFlags(kArchCallCodeObject, flags);
2988       break;
2989     case CallDescriptor::kCallJSFunction:
2990       opcode = EncodeCallDescriptorFlags(kArchCallJSFunction, flags);
2991       break;
2992 #if V8_ENABLE_WEBASSEMBLY
2993     case CallDescriptor::kCallWasmCapiFunction:
2994     case CallDescriptor::kCallWasmFunction:
2995     case CallDescriptor::kCallWasmImportWrapper:
2996       opcode = EncodeCallDescriptorFlags(kArchCallWasmFunction, flags);
2997       break;
2998 #endif  // V8_ENABLE_WEBASSEMBLY
2999     case CallDescriptor::kCallBuiltinPointer:
3000       opcode = EncodeCallDescriptorFlags(kArchCallBuiltinPointer, flags);
3001       break;
3002   }
3003 
3004   // Emit the call instruction.
3005   size_t const output_count = buffer.outputs.size();
3006   auto* outputs = output_count ? &buffer.outputs.front() : nullptr;
3007   Instruction* call_instr =
3008       Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
3009            &buffer.instruction_args.front());
3010   if (instruction_selection_failed()) return;
3011   call_instr->MarkAsCall();
3012 
3013   EmitPrepareResults(&(buffer.output_nodes), call_descriptor, node);
3014 
3015   if (call_descriptor->NeedsCallerSavedRegisters()) {
3016     Emit(
3017         kArchRestoreCallerRegisters | MiscField::encode(static_cast<int>(mode)),
3018         g.NoOutput());
3019   }
3020 }
3021 
VisitTailCall(Node * node)3022 void InstructionSelector::VisitTailCall(Node* node) {
3023   OperandGenerator g(this);
3024 
3025   auto caller = linkage()->GetIncomingDescriptor();
3026   auto callee = CallDescriptorOf(node->op());
3027   DCHECK(caller->CanTailCall(callee));
3028   const int stack_param_delta = callee->GetStackParameterDelta(caller);
3029   CallBuffer buffer(zone(), callee, nullptr);
3030 
3031   // Compute InstructionOperands for inputs and outputs.
3032   CallBufferFlags flags(kCallCodeImmediate | kCallTail);
3033   if (IsTailCallAddressImmediate()) {
3034     flags |= kCallAddressImmediate;
3035   }
3036   if (callee->flags() & CallDescriptor::kFixedTargetRegister) {
3037     flags |= kCallFixedTargetRegister;
3038   }
3039   InitializeCallBuffer(node, &buffer, flags, stack_param_delta);
3040   UpdateMaxPushedArgumentCount(stack_param_delta);
3041 
3042   // Select the appropriate opcode based on the call type.
3043   InstructionCode opcode;
3044   InstructionOperandVector temps(zone());
3045   switch (callee->kind()) {
3046     case CallDescriptor::kCallCodeObject:
3047       opcode = kArchTailCallCodeObject;
3048       break;
3049     case CallDescriptor::kCallAddress:
3050       DCHECK(!caller->IsJSFunctionCall());
3051       opcode = kArchTailCallAddress;
3052       break;
3053 #if V8_ENABLE_WEBASSEMBLY
3054     case CallDescriptor::kCallWasmFunction:
3055       DCHECK(!caller->IsJSFunctionCall());
3056       opcode = kArchTailCallWasm;
3057       break;
3058 #endif  // V8_ENABLE_WEBASSEMBLY
3059     default:
3060       UNREACHABLE();
3061   }
3062   opcode = EncodeCallDescriptorFlags(opcode, callee->flags());
3063 
3064   Emit(kArchPrepareTailCall, g.NoOutput());
3065 
3066   // Add an immediate operand that represents the offset to the first slot that
3067   // is unused with respect to the stack pointer that has been updated for the
3068   // tail call instruction. Backends that pad arguments can write the padding
3069   // value at this offset from the stack.
3070   const int optional_padding_offset =
3071       callee->GetOffsetToFirstUnusedStackSlot() - 1;
3072   buffer.instruction_args.push_back(g.TempImmediate(optional_padding_offset));
3073 
3074   const int first_unused_slot_offset =
3075       kReturnAddressStackSlotCount + stack_param_delta;
3076   buffer.instruction_args.push_back(g.TempImmediate(first_unused_slot_offset));
3077 
3078   // Emit the tailcall instruction.
3079   Emit(opcode, 0, nullptr, buffer.instruction_args.size(),
3080        &buffer.instruction_args.front(), temps.size(),
3081        temps.empty() ? nullptr : &temps.front());
3082 }
3083 
VisitGoto(BasicBlock * target)3084 void InstructionSelector::VisitGoto(BasicBlock* target) {
3085   // jump to the next block.
3086   OperandGenerator g(this);
3087   Emit(kArchJmp, g.NoOutput(), g.Label(target));
3088 }
3089 
VisitReturn(Node * ret)3090 void InstructionSelector::VisitReturn(Node* ret) {
3091   OperandGenerator g(this);
3092   const int input_count = linkage()->GetIncomingDescriptor()->ReturnCount() == 0
3093                               ? 1
3094                               : ret->op()->ValueInputCount();
3095   DCHECK_GE(input_count, 1);
3096   auto value_locations = zone()->NewArray<InstructionOperand>(input_count);
3097   Node* pop_count = ret->InputAt(0);
3098   value_locations[0] = (pop_count->opcode() == IrOpcode::kInt32Constant ||
3099                         pop_count->opcode() == IrOpcode::kInt64Constant)
3100                            ? g.UseImmediate(pop_count)
3101                            : g.UseRegister(pop_count);
3102   for (int i = 1; i < input_count; ++i) {
3103     value_locations[i] =
3104         g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i - 1));
3105   }
3106   Emit(kArchRet, 0, nullptr, input_count, value_locations);
3107 }
3108 
VisitBranch(Node * branch,BasicBlock * tbranch,BasicBlock * fbranch)3109 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
3110                                       BasicBlock* fbranch) {
3111   FlagsContinuation cont =
3112       FlagsContinuation::ForBranch(kNotEqual, tbranch, fbranch);
3113   VisitWordCompareZero(branch, branch->InputAt(0), &cont);
3114 }
3115 
VisitDeoptimizeIf(Node * node)3116 void InstructionSelector::VisitDeoptimizeIf(Node* node) {
3117   DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
3118   FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
3119       kNotEqual, p.reason(), node->id(), p.feedback(),
3120       FrameState{node->InputAt(1)});
3121   VisitWordCompareZero(node, node->InputAt(0), &cont);
3122 }
3123 
VisitDeoptimizeUnless(Node * node)3124 void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
3125   DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
3126   FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
3127       kEqual, p.reason(), node->id(), p.feedback(),
3128       FrameState{node->InputAt(1)});
3129   VisitWordCompareZero(node, node->InputAt(0), &cont);
3130 }
3131 
VisitSelect(Node * node)3132 void InstructionSelector::VisitSelect(Node* node) {
3133   FlagsContinuation cont =
3134       FlagsContinuation::ForSelect(kNotEqual, node,
3135                                    node->InputAt(1), node->InputAt(2));
3136   VisitWordCompareZero(node, node->InputAt(0), &cont);
3137 }
3138 
VisitTrapIf(Node * node,TrapId trap_id)3139 void InstructionSelector::VisitTrapIf(Node* node, TrapId trap_id) {
3140   FlagsContinuation cont =
3141       FlagsContinuation::ForTrap(kNotEqual, trap_id, node->InputAt(1));
3142   VisitWordCompareZero(node, node->InputAt(0), &cont);
3143 }
3144 
VisitTrapUnless(Node * node,TrapId trap_id)3145 void InstructionSelector::VisitTrapUnless(Node* node, TrapId trap_id) {
3146   FlagsContinuation cont =
3147       FlagsContinuation::ForTrap(kEqual, trap_id, node->InputAt(1));
3148   VisitWordCompareZero(node, node->InputAt(0), &cont);
3149 }
3150 
EmitIdentity(Node * node)3151 void InstructionSelector::EmitIdentity(Node* node) {
3152   MarkAsUsed(node->InputAt(0));
3153   SetRename(node, node->InputAt(0));
3154 }
3155 
VisitDeoptimize(DeoptimizeReason reason,NodeId node_id,FeedbackSource const & feedback,FrameState frame_state)3156 void InstructionSelector::VisitDeoptimize(DeoptimizeReason reason,
3157                                           NodeId node_id,
3158                                           FeedbackSource const& feedback,
3159                                           FrameState frame_state) {
3160   InstructionOperandVector args(instruction_zone());
3161   AppendDeoptimizeArguments(&args, reason, node_id, feedback, frame_state);
3162   Emit(kArchDeoptimize, 0, nullptr, args.size(), &args.front(), 0, nullptr);
3163 }
3164 
VisitThrow(Node * node)3165 void InstructionSelector::VisitThrow(Node* node) {
3166   OperandGenerator g(this);
3167   Emit(kArchThrowTerminator, g.NoOutput());
3168 }
3169 
VisitDebugBreak(Node * node)3170 void InstructionSelector::VisitDebugBreak(Node* node) {
3171   OperandGenerator g(this);
3172   Emit(kArchDebugBreak, g.NoOutput());
3173 }
3174 
VisitUnreachable(Node * node)3175 void InstructionSelector::VisitUnreachable(Node* node) {
3176   OperandGenerator g(this);
3177   Emit(kArchDebugBreak, g.NoOutput());
3178 }
3179 
VisitStaticAssert(Node * node)3180 void InstructionSelector::VisitStaticAssert(Node* node) {
3181   Node* asserted = node->InputAt(0);
3182   UnparkedScopeIfNeeded scope(broker_);
3183   AllowHandleDereference allow_handle_dereference;
3184   asserted->Print(4);
3185   FATAL(
3186       "Expected Turbofan static assert to hold, but got non-true input:\n  %s",
3187       StaticAssertSourceOf(node->op()));
3188 }
3189 
VisitDeadValue(Node * node)3190 void InstructionSelector::VisitDeadValue(Node* node) {
3191   OperandGenerator g(this);
3192   MarkAsRepresentation(DeadValueRepresentationOf(node->op()), node);
3193   Emit(kArchDebugBreak, g.DefineAsConstant(node));
3194 }
3195 
VisitComment(Node * node)3196 void InstructionSelector::VisitComment(Node* node) {
3197   OperandGenerator g(this);
3198   InstructionOperand operand(g.UseImmediate(node));
3199   Emit(kArchComment, 0, nullptr, 1, &operand);
3200 }
3201 
VisitUnsafePointerAdd(Node * node)3202 void InstructionSelector::VisitUnsafePointerAdd(Node* node) {
3203 #if V8_TARGET_ARCH_64_BIT
3204   VisitInt64Add(node);
3205 #else   // V8_TARGET_ARCH_64_BIT
3206   VisitInt32Add(node);
3207 #endif  // V8_TARGET_ARCH_64_BIT
3208 }
3209 
VisitRetain(Node * node)3210 void InstructionSelector::VisitRetain(Node* node) {
3211   OperandGenerator g(this);
3212   Emit(kArchNop, g.NoOutput(), g.UseAny(node->InputAt(0)));
3213 }
3214 
CanProduceSignalingNaN(Node * node)3215 bool InstructionSelector::CanProduceSignalingNaN(Node* node) {
3216   // TODO(jarin) Improve the heuristic here.
3217   if (node->opcode() == IrOpcode::kFloat64Add ||
3218       node->opcode() == IrOpcode::kFloat64Sub ||
3219       node->opcode() == IrOpcode::kFloat64Mul) {
3220     return false;
3221   }
3222   return true;
3223 }
3224 
3225 #if V8_TARGET_ARCH_64_BIT
ZeroExtendsWord32ToWord64(Node * node,int recursion_depth)3226 bool InstructionSelector::ZeroExtendsWord32ToWord64(Node* node,
3227                                                     int recursion_depth) {
3228   // To compute whether a Node sets its upper 32 bits to zero, there are three
3229   // cases.
3230   // 1. Phi node, with a computed result already available in phi_states_:
3231   //    Read the value from phi_states_.
3232   // 2. Phi node, with no result available in phi_states_ yet:
3233   //    Recursively check its inputs, and store the result in phi_states_.
3234   // 3. Anything else:
3235   //    Call the architecture-specific ZeroExtendsWord32ToWord64NoPhis.
3236 
3237   // Limit recursion depth to avoid the possibility of stack overflow on very
3238   // large functions.
3239   const int kMaxRecursionDepth = 100;
3240 
3241   if (node->opcode() == IrOpcode::kPhi) {
3242     Upper32BitsState current = phi_states_[node->id()];
3243     if (current != Upper32BitsState::kNotYetChecked) {
3244       return current == Upper32BitsState::kUpperBitsGuaranteedZero;
3245     }
3246 
3247     // If further recursion is prevented, we can't make any assumptions about
3248     // the output of this phi node.
3249     if (recursion_depth >= kMaxRecursionDepth) {
3250       return false;
3251     }
3252 
3253     // Mark the current node so that we skip it if we recursively visit it
3254     // again. Or, said differently, we compute a largest fixed-point so we can
3255     // be optimistic when we hit cycles.
3256     phi_states_[node->id()] = Upper32BitsState::kUpperBitsGuaranteedZero;
3257 
3258     int input_count = node->op()->ValueInputCount();
3259     for (int i = 0; i < input_count; ++i) {
3260       Node* input = NodeProperties::GetValueInput(node, i);
3261       if (!ZeroExtendsWord32ToWord64(input, recursion_depth + 1)) {
3262         phi_states_[node->id()] = Upper32BitsState::kNoGuarantee;
3263         return false;
3264       }
3265     }
3266 
3267     return true;
3268   }
3269   return ZeroExtendsWord32ToWord64NoPhis(node);
3270 }
3271 #endif  // V8_TARGET_ARCH_64_BIT
3272 
3273 namespace {
3274 
GetFrameStateDescriptorInternal(Zone * zone,FrameState state)3275 FrameStateDescriptor* GetFrameStateDescriptorInternal(Zone* zone,
3276                                                       FrameState state) {
3277   DCHECK_EQ(IrOpcode::kFrameState, state->opcode());
3278   DCHECK_EQ(FrameState::kFrameStateInputCount, state->InputCount());
3279   const FrameStateInfo& state_info = FrameStateInfoOf(state->op());
3280   int parameters = state_info.parameter_count();
3281   int locals = state_info.local_count();
3282   int stack = state_info.type() == FrameStateType::kUnoptimizedFunction ? 1 : 0;
3283 
3284   FrameStateDescriptor* outer_state = nullptr;
3285   if (state.outer_frame_state()->opcode() == IrOpcode::kFrameState) {
3286     outer_state = GetFrameStateDescriptorInternal(
3287         zone, FrameState{state.outer_frame_state()});
3288   }
3289 
3290 #if V8_ENABLE_WEBASSEMBLY
3291   if (state_info.type() == FrameStateType::kJSToWasmBuiltinContinuation) {
3292     auto function_info = static_cast<const JSToWasmFrameStateFunctionInfo*>(
3293         state_info.function_info());
3294     return zone->New<JSToWasmFrameStateDescriptor>(
3295         zone, state_info.type(), state_info.bailout_id(),
3296         state_info.state_combine(), parameters, locals, stack,
3297         state_info.shared_info(), outer_state, function_info->signature());
3298   }
3299 #endif  // V8_ENABLE_WEBASSEMBLY
3300 
3301   return zone->New<FrameStateDescriptor>(
3302       zone, state_info.type(), state_info.bailout_id(),
3303       state_info.state_combine(), parameters, locals, stack,
3304       state_info.shared_info(), outer_state);
3305 }
3306 
3307 }  // namespace
3308 
GetFrameStateDescriptor(FrameState state)3309 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
3310     FrameState state) {
3311   auto* desc = GetFrameStateDescriptorInternal(instruction_zone(), state);
3312   *max_unoptimized_frame_height_ =
3313       std::max(*max_unoptimized_frame_height_,
3314                desc->total_conservative_frame_size_in_bytes());
3315   return desc;
3316 }
3317 
3318 #if V8_ENABLE_WEBASSEMBLY
CanonicalizeShuffle(Node * node,uint8_t * shuffle,bool * is_swizzle)3319 void InstructionSelector::CanonicalizeShuffle(Node* node, uint8_t* shuffle,
3320                                               bool* is_swizzle) {
3321   // Get raw shuffle indices.
3322   memcpy(shuffle, S128ImmediateParameterOf(node->op()).data(), kSimd128Size);
3323   bool needs_swap;
3324   bool inputs_equal = GetVirtualRegister(node->InputAt(0)) ==
3325                       GetVirtualRegister(node->InputAt(1));
3326   wasm::SimdShuffle::CanonicalizeShuffle(inputs_equal, shuffle, &needs_swap,
3327                                          is_swizzle);
3328   if (needs_swap) {
3329     SwapShuffleInputs(node);
3330   }
3331   // Duplicate the first input; for some shuffles on some architectures, it's
3332   // easiest to implement a swizzle as a shuffle so it might be used.
3333   if (*is_swizzle) {
3334     node->ReplaceInput(1, node->InputAt(0));
3335   }
3336 }
3337 
3338 // static
SwapShuffleInputs(Node * node)3339 void InstructionSelector::SwapShuffleInputs(Node* node) {
3340   Node* input0 = node->InputAt(0);
3341   Node* input1 = node->InputAt(1);
3342   node->ReplaceInput(0, input1);
3343   node->ReplaceInput(1, input0);
3344 }
3345 #endif  // V8_ENABLE_WEBASSEMBLY
3346 
3347 }  // namespace compiler
3348 }  // namespace internal
3349 }  // namespace v8
3350