Line data Source code
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/instruction-selector.h"
6 :
7 : #include <limits>
8 :
9 : #include "src/assembler-inl.h"
10 : #include "src/base/adapters.h"
11 : #include "src/compiler/compiler-source-position-table.h"
12 : #include "src/compiler/instruction-selector-impl.h"
13 : #include "src/compiler/node-matchers.h"
14 : #include "src/compiler/pipeline.h"
15 : #include "src/compiler/schedule.h"
16 : #include "src/compiler/state-values-utils.h"
17 : #include "src/deoptimizer.h"
18 : #include "src/objects-inl.h"
19 :
20 : namespace v8 {
21 : namespace internal {
22 : namespace compiler {
23 :
24 916090 : InstructionSelector::InstructionSelector(
25 : Zone* zone, size_t node_count, Linkage* linkage,
26 : InstructionSequence* sequence, Schedule* schedule,
27 : SourcePositionTable* source_positions, Frame* frame,
28 : SourcePositionMode source_position_mode, Features features,
29 : EnableScheduling enable_scheduling,
30 : EnableSerialization enable_serialization)
31 : : zone_(zone),
32 : linkage_(linkage),
33 : sequence_(sequence),
34 : source_positions_(source_positions),
35 : source_position_mode_(source_position_mode),
36 : features_(features),
37 : schedule_(schedule),
38 : current_block_(nullptr),
39 : instructions_(zone),
40 : defined_(node_count, false, zone),
41 : used_(node_count, false, zone),
42 : effect_level_(node_count, 0, zone),
43 : virtual_registers_(node_count,
44 : InstructionOperand::kInvalidVirtualRegister, zone),
45 : virtual_register_rename_(zone),
46 : scheduler_(nullptr),
47 : enable_scheduling_(enable_scheduling),
48 : enable_serialization_(enable_serialization),
49 : frame_(frame),
50 1832205 : instruction_selection_failed_(false) {
51 916115 : instructions_.reserve(node_count);
52 916118 : }
53 :
54 24755749 : bool InstructionSelector::SelectInstructions() {
55 : // Mark the inputs of all phis in loop headers as used.
56 : BasicBlockVector* blocks = schedule()->rpo_order();
57 13294167 : for (auto const block : *blocks) {
58 11461935 : if (!block->IsLoopHeader()) continue;
59 : DCHECK_LE(2u, block->PredecessorCount());
60 1073998 : for (Node* const phi : *block) {
61 867390 : if (phi->opcode() != IrOpcode::kPhi) continue;
62 :
63 : // Mark all inputs as used.
64 793169 : for (Node* const input : phi->inputs()) {
65 : MarkAsUsed(input);
66 : }
67 : }
68 : }
69 :
70 : // Visit each basic block in post order.
71 12377886 : for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) {
72 11461780 : VisitBlock(*i);
73 11461765 : if (instruction_selection_failed()) return false;
74 : }
75 :
76 : // Schedule the selected instructions.
77 916106 : if (UseInstructionScheduling()) {
78 0 : scheduler_ = new (zone()) InstructionScheduler(zone(), sequence());
79 : }
80 :
81 36217519 : for (auto const block : *blocks) {
82 22923528 : InstructionBlock* instruction_block =
83 11461762 : sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
84 25590674 : for (size_t i = 0; i < instruction_block->phis().size(); i++) {
85 1333573 : UpdateRenamesInPhi(instruction_block->PhiAt(i));
86 : }
87 11461764 : size_t end = instruction_block->code_end();
88 11461764 : size_t start = instruction_block->code_start();
89 : DCHECK_LE(end, start);
90 11461764 : StartBlock(RpoNumber::FromInt(block->rpo_number()));
91 61136972 : while (start-- > end) {
92 76426788 : UpdateRenames(instructions_[start]);
93 38213465 : AddInstruction(instructions_[start]);
94 : }
95 11461798 : EndBlock(RpoNumber::FromInt(block->rpo_number()));
96 : }
97 : #if DEBUG
98 : sequence()->ValidateSSA();
99 : #endif
100 : return true;
101 : }
102 :
103 22923508 : void InstructionSelector::StartBlock(RpoNumber rpo) {
104 11461754 : if (UseInstructionScheduling()) {
105 : DCHECK_NOT_NULL(scheduler_);
106 0 : scheduler_->StartBlock(rpo);
107 : } else {
108 11461754 : sequence()->StartBlock(rpo);
109 : }
110 11461788 : }
111 :
112 :
113 22923548 : void InstructionSelector::EndBlock(RpoNumber rpo) {
114 11461774 : if (UseInstructionScheduling()) {
115 : DCHECK_NOT_NULL(scheduler_);
116 0 : scheduler_->EndBlock(rpo);
117 : } else {
118 11461774 : sequence()->EndBlock(rpo);
119 : }
120 11461764 : }
121 :
122 :
123 76426960 : void InstructionSelector::AddInstruction(Instruction* instr) {
124 38213480 : if (UseInstructionScheduling()) {
125 : DCHECK_NOT_NULL(scheduler_);
126 0 : scheduler_->AddInstruction(instr);
127 : } else {
128 38213480 : sequence()->AddInstruction(instr);
129 : }
130 38213449 : }
131 :
132 11341846 : Instruction* InstructionSelector::Emit(InstructionCode opcode,
133 : InstructionOperand output,
134 : size_t temp_count,
135 : InstructionOperand* temps) {
136 11341846 : size_t output_count = output.IsInvalid() ? 0 : 1;
137 11341846 : return Emit(opcode, output_count, &output, 0, nullptr, temp_count, temps);
138 : }
139 :
140 :
141 10539285 : Instruction* InstructionSelector::Emit(InstructionCode opcode,
142 : InstructionOperand output,
143 : InstructionOperand a, size_t temp_count,
144 : InstructionOperand* temps) {
145 10539285 : size_t output_count = output.IsInvalid() ? 0 : 1;
146 10539285 : return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
147 : }
148 :
149 :
150 1467708 : Instruction* InstructionSelector::Emit(InstructionCode opcode,
151 : InstructionOperand output,
152 : InstructionOperand a,
153 : InstructionOperand b, size_t temp_count,
154 : InstructionOperand* temps) {
155 1467708 : size_t output_count = output.IsInvalid() ? 0 : 1;
156 1467708 : InstructionOperand inputs[] = {a, b};
157 : size_t input_count = arraysize(inputs);
158 : return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
159 1467708 : temps);
160 : }
161 :
162 :
163 14234 : Instruction* InstructionSelector::Emit(InstructionCode opcode,
164 : InstructionOperand output,
165 : InstructionOperand a,
166 : InstructionOperand b,
167 : InstructionOperand c, size_t temp_count,
168 : InstructionOperand* temps) {
169 14234 : size_t output_count = output.IsInvalid() ? 0 : 1;
170 14234 : InstructionOperand inputs[] = {a, b, c};
171 : size_t input_count = arraysize(inputs);
172 : return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
173 14234 : temps);
174 : }
175 :
176 :
177 2268984 : Instruction* InstructionSelector::Emit(
178 : InstructionCode opcode, InstructionOperand output, InstructionOperand a,
179 : InstructionOperand b, InstructionOperand c, InstructionOperand d,
180 : size_t temp_count, InstructionOperand* temps) {
181 2268984 : size_t output_count = output.IsInvalid() ? 0 : 1;
182 2268984 : InstructionOperand inputs[] = {a, b, c, d};
183 : size_t input_count = arraysize(inputs);
184 : return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
185 2268984 : temps);
186 : }
187 :
188 :
189 53151 : Instruction* InstructionSelector::Emit(
190 : InstructionCode opcode, InstructionOperand output, InstructionOperand a,
191 : InstructionOperand b, InstructionOperand c, InstructionOperand d,
192 : InstructionOperand e, size_t temp_count, InstructionOperand* temps) {
193 53151 : size_t output_count = output.IsInvalid() ? 0 : 1;
194 53151 : InstructionOperand inputs[] = {a, b, c, d, e};
195 : size_t input_count = arraysize(inputs);
196 : return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
197 53151 : temps);
198 : }
199 :
200 :
201 0 : Instruction* InstructionSelector::Emit(
202 : InstructionCode opcode, InstructionOperand output, InstructionOperand a,
203 : InstructionOperand b, InstructionOperand c, InstructionOperand d,
204 : InstructionOperand e, InstructionOperand f, size_t temp_count,
205 : InstructionOperand* temps) {
206 0 : size_t output_count = output.IsInvalid() ? 0 : 1;
207 0 : InstructionOperand inputs[] = {a, b, c, d, e, f};
208 : size_t input_count = arraysize(inputs);
209 : return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
210 0 : temps);
211 : }
212 :
213 :
214 38212900 : Instruction* InstructionSelector::Emit(
215 : InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
216 : size_t input_count, InstructionOperand* inputs, size_t temp_count,
217 : InstructionOperand* temps) {
218 76425800 : if (output_count >= Instruction::kMaxOutputCount ||
219 76425722 : input_count >= Instruction::kMaxInputCount ||
220 : temp_count >= Instruction::kMaxTempCount) {
221 : set_instruction_selection_failed();
222 0 : return nullptr;
223 : }
224 :
225 : Instruction* instr =
226 : Instruction::New(instruction_zone(), opcode, output_count, outputs,
227 38212900 : input_count, inputs, temp_count, temps);
228 38213063 : return Emit(instr);
229 : }
230 :
231 :
232 0 : Instruction* InstructionSelector::Emit(Instruction* instr) {
233 38213101 : instructions_.push_back(instr);
234 38213063 : return instr;
235 : }
236 :
237 :
238 25492639 : bool InstructionSelector::CanCover(Node* user, Node* node) const {
239 : // 1. Both {user} and {node} must be in the same basic block.
240 14126939 : if (schedule()->block(node) != schedule()->block(user)) {
241 : return false;
242 : }
243 : // 2. Pure {node}s must be owned by the {user}.
244 6412610 : if (node->op()->HasProperty(Operator::kPure)) {
245 4953090 : return node->OwnedBy(user);
246 : }
247 : // 3. Impure {node}s must match the effect level of {user}.
248 1459520 : if (GetEffectLevel(node) != GetEffectLevel(user)) {
249 : return false;
250 : }
251 : // 4. Only {node} must have value edges pointing to {user}.
252 6474777 : for (Edge const edge : node->use_edges()) {
253 2575734 : if (edge.from() != user && NodeProperties::IsValueEdge(edge)) {
254 107848 : return false;
255 : }
256 : }
257 1323309 : return true;
258 : }
259 :
260 0 : bool InstructionSelector::IsOnlyUserOfNodeInSameBlock(Node* user,
261 0 : Node* node) const {
262 0 : BasicBlock* bb_user = schedule()->block(user);
263 0 : BasicBlock* bb_node = schedule()->block(node);
264 0 : if (bb_user != bb_node) return false;
265 0 : for (Edge const edge : node->use_edges()) {
266 : Node* from = edge.from();
267 0 : if ((from != user) && (schedule()->block(from) == bb_user)) {
268 : return false;
269 : }
270 : }
271 0 : return true;
272 : }
273 :
274 158682022 : void InstructionSelector::UpdateRenames(Instruction* instruction) {
275 240937242 : for (size_t i = 0; i < instruction->InputCount(); i++) {
276 82255131 : TryRename(instruction->InputAt(i));
277 : }
278 38213490 : }
279 :
280 1333568 : void InstructionSelector::UpdateRenamesInPhi(PhiInstruction* phi) {
281 9318182 : for (size_t i = 0; i < phi->operands().size(); i++) {
282 3325519 : int vreg = phi->operands()[i];
283 : int renamed = GetRename(vreg);
284 3325519 : if (vreg != renamed) {
285 15973 : phi->RenameInput(i, renamed);
286 : }
287 : }
288 1333572 : }
289 :
290 0 : int InstructionSelector::GetRename(int virtual_register) {
291 : int rename = virtual_register;
292 : while (true) {
293 98990936 : if (static_cast<size_t>(rename) >= virtual_register_rename_.size()) break;
294 8938224 : int next = virtual_register_rename_[rename];
295 8938224 : if (next == InstructionOperand::kInvalidVirtualRegister) {
296 : break;
297 : }
298 : rename = next;
299 : }
300 0 : return rename;
301 : }
302 :
303 82255149 : void InstructionSelector::TryRename(InstructionOperand* op) {
304 164510298 : if (!op->IsUnallocated()) return;
305 : int vreg = UnallocatedOperand::cast(op)->virtual_register();
306 : int rename = GetRename(vreg);
307 46029119 : if (rename != vreg) {
308 : UnallocatedOperand::cast(op)->set_virtual_register(rename);
309 : }
310 : }
311 :
312 110406 : void InstructionSelector::SetRename(const Node* node, const Node* rename) {
313 110406 : int vreg = GetVirtualRegister(node);
314 331221 : if (static_cast<size_t>(vreg) >= virtual_register_rename_.size()) {
315 104260 : int invalid = InstructionOperand::kInvalidVirtualRegister;
316 104260 : virtual_register_rename_.resize(vreg + 1, invalid);
317 : }
318 110407 : virtual_register_rename_[vreg] = GetVirtualRegister(rename);
319 110407 : }
320 :
321 115187137 : int InstructionSelector::GetVirtualRegister(const Node* node) {
322 : DCHECK_NOT_NULL(node);
323 92321468 : size_t const id = node->id();
324 : DCHECK_LT(id, virtual_registers_.size());
325 207508680 : int virtual_register = virtual_registers_[id];
326 92321468 : if (virtual_register == InstructionOperand::kInvalidVirtualRegister) {
327 22865669 : virtual_register = sequence()->NextVirtualRegister();
328 22865744 : virtual_registers_[id] = virtual_register;
329 : }
330 92321543 : return virtual_register;
331 : }
332 :
333 :
334 242 : const std::map<NodeId, int> InstructionSelector::GetVirtualRegistersForTesting()
335 : const {
336 : std::map<NodeId, int> virtual_registers;
337 4502 : for (size_t n = 0; n < virtual_registers_.size(); ++n) {
338 4260 : if (virtual_registers_[n] != InstructionOperand::kInvalidVirtualRegister) {
339 705 : NodeId const id = static_cast<NodeId>(n);
340 1410 : virtual_registers.insert(std::make_pair(id, virtual_registers_[n]));
341 : }
342 : }
343 242 : return virtual_registers;
344 : }
345 :
346 :
347 26318889 : bool InstructionSelector::IsDefined(Node* node) const {
348 : DCHECK_NOT_NULL(node);
349 26318889 : size_t const id = node->id();
350 : DCHECK_LT(id, defined_.size());
351 26801374 : return defined_[id];
352 : }
353 :
354 :
355 21422003 : void InstructionSelector::MarkAsDefined(Node* node) {
356 : DCHECK_NOT_NULL(node);
357 21422003 : size_t const id = node->id();
358 : DCHECK_LT(id, defined_.size());
359 21422003 : defined_[id] = true;
360 6350598 : }
361 :
362 :
363 115698861 : bool InstructionSelector::IsUsed(Node* node) const {
364 : DCHECK_NOT_NULL(node);
365 : // TODO(bmeurer): This is a terrible monster hack, but we have to make sure
366 : // that the Retain is actually emitted, otherwise the GC will mess up.
367 60995867 : if (node->opcode() == IrOpcode::kRetain) return true;
368 60989465 : if (!node->op()->HasProperty(Operator::kEliminatable)) return true;
369 54702994 : size_t const id = node->id();
370 : DCHECK_LT(id, used_.size());
371 109405988 : return used_[id];
372 : }
373 :
374 :
375 53865272 : void InstructionSelector::MarkAsUsed(Node* node) {
376 : DCHECK_NOT_NULL(node);
377 53865272 : size_t const id = node->id();
378 : DCHECK_LT(id, used_.size());
379 53865272 : used_[id] = true;
380 18631297 : }
381 :
382 10839604 : int InstructionSelector::GetEffectLevel(Node* node) const {
383 : DCHECK_NOT_NULL(node);
384 10839604 : size_t const id = node->id();
385 : DCHECK_LT(id, effect_level_.size());
386 20219688 : return effect_level_[id];
387 : }
388 :
389 65444792 : void InstructionSelector::SetEffectLevel(Node* node, int effect_level) {
390 : DCHECK_NOT_NULL(node);
391 65444792 : size_t const id = node->id();
392 : DCHECK_LT(id, effect_level_.size());
393 130889584 : effect_level_[id] = effect_level;
394 0 : }
395 :
396 5688921 : bool InstructionSelector::CanAddressRelativeToRootsRegister() const {
397 10279007 : return enable_serialization_ == kDisableSerialization &&
398 5688921 : CanUseRootsRegister();
399 : }
400 :
401 6615168 : bool InstructionSelector::CanUseRootsRegister() const {
402 : return linkage()->GetIncomingDescriptor()->flags() &
403 2025082 : CallDescriptor::kCanUseRoots;
404 : }
405 :
406 0 : void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
407 3503003 : const InstructionOperand& op) {
408 : UnallocatedOperand unalloc = UnallocatedOperand::cast(op);
409 3503003 : sequence()->MarkAsRepresentation(rep, unalloc.virtual_register());
410 0 : }
411 :
412 :
413 12881146 : void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
414 12881197 : Node* node) {
415 25762343 : sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node));
416 12881207 : }
417 :
418 : namespace {
419 :
420 18966275 : InstructionOperand OperandForDeopt(Isolate* isolate, OperandGenerator* g,
421 18966271 : Node* input, FrameStateInputKind kind,
422 : MachineRepresentation rep) {
423 18966275 : if (rep == MachineRepresentation::kNone) {
424 4 : return g->TempImmediate(FrameStateDescriptor::kImpossibleValue);
425 : }
426 :
427 18966271 : switch (input->opcode()) {
428 : case IrOpcode::kInt32Constant:
429 : case IrOpcode::kInt64Constant:
430 : case IrOpcode::kNumberConstant:
431 : case IrOpcode::kFloat32Constant:
432 : case IrOpcode::kFloat64Constant:
433 971181 : return g->UseImmediate(input);
434 : case IrOpcode::kHeapConstant: {
435 4393350 : if (!CanBeTaggedPointer(rep)) {
436 : // If we have inconsistent static and dynamic types, e.g. if we
437 : // smi-check a string, we can get here with a heap object that
438 : // says it is a smi. In that case, we return an invalid instruction
439 : // operand, which will be interpreted as an optimized-out value.
440 :
441 : // TODO(jarin) Ideally, we should turn the current instruction
442 : // into an abort (we should never execute it).
443 0 : return InstructionOperand();
444 : }
445 :
446 4393350 : Handle<HeapObject> constant = OpParameter<Handle<HeapObject>>(input);
447 : Heap::RootListIndex root_index;
448 4393350 : if (isolate->heap()->IsRootHandle(constant, &root_index) &&
449 : root_index == Heap::kOptimizedOutRootIndex) {
450 : // For an optimized-out object we return an invalid instruction
451 : // operand, so that we take the fast path for optimized-out values.
452 205 : return InstructionOperand();
453 : }
454 :
455 4393145 : return g->UseImmediate(input);
456 : }
457 : case IrOpcode::kArgumentsElementsState:
458 : case IrOpcode::kArgumentsLengthState:
459 : case IrOpcode::kObjectState:
460 : case IrOpcode::kTypedObjectState:
461 0 : UNREACHABLE();
462 : break;
463 : default:
464 13601740 : switch (kind) {
465 : case FrameStateInputKind::kStackSlot:
466 12140969 : return g->UseUniqueSlot(input);
467 : case FrameStateInputKind::kAny:
468 : // Currently deopts "wrap" other operations, so the deopt's inputs
469 : // are potentially needed untill the end of the deoptimising code.
470 1460771 : return g->UseAnyAtEnd(input);
471 : }
472 : }
473 0 : UNREACHABLE();
474 : return InstructionOperand();
475 : }
476 :
477 : } // namespace
478 :
479 : class StateObjectDeduplicator {
480 : public:
481 : explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {}
482 : static const size_t kNotDuplicated = SIZE_MAX;
483 :
484 : size_t GetObjectId(Node* node) {
485 23491 : for (size_t i = 0; i < objects_.size(); ++i) {
486 24991 : if (objects_[i] == node) {
487 : return i;
488 : }
489 : }
490 : return kNotDuplicated;
491 : }
492 :
493 : size_t InsertObject(Node* node) {
494 : size_t id = objects_.size();
495 17771 : objects_.push_back(node);
496 : return id;
497 : }
498 :
499 : private:
500 : ZoneVector<Node*> objects_;
501 : };
502 :
503 : // Returns the number of instruction operands added to inputs.
504 45041028 : size_t InstructionSelector::AddOperandToStateValueDescriptor(
505 : StateValueList* values, InstructionOperandVector* inputs,
506 19000177 : OperandGenerator* g, StateObjectDeduplicator* deduplicator, Node* input,
507 : MachineType type, FrameStateInputKind kind, Zone* zone) {
508 45041028 : if (input == nullptr) {
509 : values->PushOptimizedOut();
510 26054746 : return 0;
511 : }
512 :
513 18986508 : switch (input->opcode()) {
514 : case IrOpcode::kArgumentsElementsState: {
515 2602 : values->PushArgumentsElements(IsRestOf(input->op()));
516 : // The elements backing store of an arguments object participates in the
517 : // duplicate object counting, but can itself never appear duplicated.
518 : DCHECK_EQ(StateObjectDeduplicator::kNotDuplicated,
519 : deduplicator->GetObjectId(input));
520 : deduplicator->InsertObject(input);
521 2602 : return 0;
522 : }
523 : case IrOpcode::kArgumentsLengthState: {
524 2634 : values->PushArgumentsLength(IsRestOf(input->op()));
525 2634 : return 0;
526 : }
527 : case IrOpcode::kObjectState: {
528 0 : UNREACHABLE();
529 : return 0;
530 : }
531 : case IrOpcode::kTypedObjectState: {
532 : size_t id = deduplicator->GetObjectId(input);
533 15169 : if (id == StateObjectDeduplicator::kNotDuplicated) {
534 : size_t entries = 0;
535 : id = deduplicator->InsertObject(input);
536 13669 : StateValueList* nested = values->PushRecursiveField(zone, id);
537 13669 : int const input_count = input->op()->ValueInputCount();
538 13669 : ZoneVector<MachineType> const* types = MachineTypesOf(input->op());
539 78149 : for (int i = 0; i < input_count; ++i) {
540 : entries += AddOperandToStateValueDescriptor(
541 64480 : nested, inputs, g, deduplicator, input->InputAt(i), types->at(i),
542 64480 : kind, zone);
543 : }
544 : return entries;
545 : } else {
546 : // Crankshaft counts duplicate objects for the running id, so we have
547 : // to push the input again.
548 : deduplicator->InsertObject(input);
549 : values->PushDuplicate(id);
550 1500 : return 0;
551 : }
552 : }
553 : default: {
554 : InstructionOperand op =
555 18966103 : OperandForDeopt(isolate(), g, input, kind, type.representation());
556 18966016 : if (op.kind() == InstructionOperand::INVALID) {
557 : // Invalid operand means the value is impossible or optimized-out.
558 : values->PushOptimizedOut();
559 211 : return 0;
560 : } else {
561 18965811 : inputs->push_back(op);
562 : values->PushPlain(type);
563 18966030 : return 1;
564 : }
565 : }
566 : }
567 : }
568 :
569 :
570 : // Returns the number of instruction operands added to inputs.
571 2916217 : size_t InstructionSelector::AddInputsToFrameStateDescriptor(
572 5832446 : FrameStateDescriptor* descriptor, Node* state, OperandGenerator* g,
573 : StateObjectDeduplicator* deduplicator, InstructionOperandVector* inputs,
574 : FrameStateInputKind kind, Zone* zone) {
575 : DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
576 :
577 : size_t entries = 0;
578 : size_t initial_size = inputs->size();
579 : USE(initial_size); // initial_size is only used for debug.
580 :
581 2916217 : if (descriptor->outer_state()) {
582 : entries += AddInputsToFrameStateDescriptor(
583 : descriptor->outer_state(), state->InputAt(kFrameStateOuterStateInput),
584 219838 : g, deduplicator, inputs, kind, zone);
585 : }
586 :
587 : Node* parameters = state->InputAt(kFrameStateParametersInput);
588 : Node* locals = state->InputAt(kFrameStateLocalsInput);
589 : Node* stack = state->InputAt(kFrameStateStackInput);
590 : Node* context = state->InputAt(kFrameStateContextInput);
591 : Node* function = state->InputAt(kFrameStateFunctionInput);
592 :
593 : DCHECK_EQ(descriptor->parameters_count(),
594 : StateValuesAccess(parameters).size());
595 : DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
596 : DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
597 :
598 2916212 : StateValueList* values_descriptor = descriptor->GetStateValueDescriptors();
599 :
600 : DCHECK_EQ(values_descriptor->size(), 0u);
601 : values_descriptor->ReserveSize(
602 2916212 : descriptor->GetSize(OutputFrameStateCombine::Ignore()));
603 :
604 : entries += AddOperandToStateValueDescriptor(
605 : values_descriptor, inputs, g, deduplicator, function,
606 2916222 : MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
607 6002769 : for (StateValuesAccess::TypedNode input_node :
608 6002718 : StateValuesAccess(parameters)) {
609 : entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
610 : deduplicator, input_node.node,
611 6002689 : input_node.type, kind, zone);
612 : }
613 2916229 : if (descriptor->HasContext()) {
614 : entries += AddOperandToStateValueDescriptor(
615 : values_descriptor, inputs, g, deduplicator, context,
616 2854489 : MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
617 : }
618 60713464 : for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
619 : entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
620 : deduplicator, input_node.node,
621 30356416 : input_node.type, kind, zone);
622 : }
623 5693167 : for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
624 : entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
625 : deduplicator, input_node.node,
626 2846575 : input_node.type, kind, zone);
627 : }
628 : DCHECK_EQ(initial_size + entries, inputs->size());
629 2916231 : return entries;
630 : }
631 :
632 :
633 : // An internal helper class for generating the operands to calls.
634 : // TODO(bmeurer): Get rid of the CallBuffer business and make
635 : // InstructionSelector::VisitCall platform independent instead.
636 : struct CallBuffer {
637 10650451 : CallBuffer(Zone* zone, const CallDescriptor* descriptor,
638 10650564 : FrameStateDescriptor* frame_state)
639 : : descriptor(descriptor),
640 : frame_state_descriptor(frame_state),
641 : output_nodes(zone),
642 : outputs(zone),
643 : instruction_args(zone),
644 3550142 : pushed_nodes(zone) {
645 3550142 : output_nodes.reserve(descriptor->ReturnCount());
646 3550167 : outputs.reserve(descriptor->ReturnCount());
647 3550182 : pushed_nodes.reserve(input_count());
648 3550191 : instruction_args.reserve(input_count() + frame_state_value_count());
649 3550165 : }
650 :
651 :
652 : const CallDescriptor* descriptor;
653 : FrameStateDescriptor* frame_state_descriptor;
654 : NodeVector output_nodes;
655 : InstructionOperandVector outputs;
656 : InstructionOperandVector instruction_args;
657 : ZoneVector<PushParameter> pushed_nodes;
658 :
659 10650505 : size_t input_count() const { return descriptor->InputCount(); }
660 :
661 : size_t frame_state_count() const { return descriptor->FrameStateCount(); }
662 :
663 : size_t frame_state_value_count() const {
664 : return (frame_state_descriptor == nullptr)
665 : ? 0
666 2413433 : : (frame_state_descriptor->GetTotalSize() +
667 5963624 : 1); // Include deopt id.
668 : }
669 : };
670 :
671 :
672 : // TODO(bmeurer): Get rid of the CallBuffer business and make
673 : // InstructionSelector::VisitCall platform independent instead.
674 7100198 : void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
675 : CallBufferFlags flags,
676 2413422 : int stack_param_delta) {
677 : OperandGenerator g(this);
678 : DCHECK_LE(call->op()->ValueOutputCount(),
679 : static_cast<int>(buffer->descriptor->ReturnCount()));
680 : DCHECK_EQ(
681 : call->op()->ValueInputCount(),
682 : static_cast<int>(buffer->input_count() + buffer->frame_state_count()));
683 :
684 20069543 : if (buffer->descriptor->ReturnCount() > 0) {
685 : // Collect the projections that represent multiple outputs from this call.
686 3499303 : if (buffer->descriptor->ReturnCount() == 1) {
687 10506276 : buffer->output_nodes.push_back(call);
688 : } else {
689 3199 : buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), nullptr);
690 41620 : for (Edge const edge : call->use_edges()) {
691 17611 : if (!NodeProperties::IsValueEdge(edge)) continue;
692 : DCHECK(edge.from()->opcode() == IrOpcode::kProjection);
693 6851 : size_t const index = ProjectionIndexOf(edge.from()->op());
694 : DCHECK_LT(index, buffer->output_nodes.size());
695 : DCHECK(!buffer->output_nodes[index]);
696 6851 : buffer->output_nodes[index] = edge.from();
697 : }
698 : }
699 :
700 : // Filter out the outputs that aren't live because no projection uses them.
701 : size_t outputs_needed_by_framestate =
702 3500084 : buffer->frame_state_descriptor == nullptr
703 : ? 0
704 : : buffer->frame_state_descriptor->state_combine()
705 6998568 : .ConsumedOutputCount();
706 10507358 : for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
707 3503961 : bool output_is_live = buffer->output_nodes[i] != nullptr ||
708 : i < outputs_needed_by_framestate;
709 3503961 : if (output_is_live) {
710 : MachineRepresentation rep =
711 3502933 : buffer->descriptor->GetReturnType(static_cast<int>(i))
712 : .representation();
713 : LinkageLocation location =
714 7005866 : buffer->descriptor->GetReturnLocation(static_cast<int>(i));
715 :
716 : Node* output = buffer->output_nodes[i];
717 : InstructionOperand op = output == nullptr
718 : ? g.TempLocation(location)
719 3502933 : : g.DefineAsLocation(output, location);
720 : MarkAsRepresentation(rep, op);
721 :
722 3503008 : buffer->outputs.push_back(op);
723 : }
724 : }
725 : }
726 :
727 : // The first argument is always the callee code.
728 6948294 : Node* callee = call->InputAt(0);
729 : bool call_code_immediate = (flags & kCallCodeImmediate) != 0;
730 : bool call_address_immediate = (flags & kCallAddressImmediate) != 0;
731 7100246 : switch (buffer->descriptor->kind()) {
732 : case CallDescriptor::kCallCodeObject:
733 : buffer->instruction_args.push_back(
734 3372351 : (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant)
735 : ? g.UseImmediate(callee)
736 10113401 : : g.UseRegister(callee));
737 3372363 : break;
738 : case CallDescriptor::kCallAddress:
739 : buffer->instruction_args.push_back(
740 25820 : (call_address_immediate &&
741 : callee->opcode() == IrOpcode::kExternalConstant)
742 : ? g.UseImmediate(callee)
743 53264 : : g.UseRegister(callee));
744 25820 : break;
745 : case CallDescriptor::kCallJSFunction:
746 : buffer->instruction_args.push_back(
747 303887 : g.UseLocation(callee, buffer->descriptor->GetInputLocation(0)));
748 151944 : break;
749 : }
750 : DCHECK_EQ(1u, buffer->instruction_args.size());
751 :
752 : // If the call needs a frame state, we insert the state information as
753 : // follows (n is the number of value inputs to the frame state):
754 : // arg 1 : deoptimization id.
755 : // arg 2 - arg (n + 1) : value inputs to the frame state.
756 : size_t frame_state_entries = 0;
757 : USE(frame_state_entries); // frame_state_entries is only used for debug.
758 3550118 : if (buffer->frame_state_descriptor != nullptr) {
759 : Node* frame_state =
760 4826844 : call->InputAt(static_cast<int>(buffer->descriptor->InputCount()));
761 :
762 : // If it was a syntactic tail call we need to drop the current frame and
763 : // all the frames on top of it that are either an arguments adaptor frame
764 : // or a tail caller frame.
765 2413422 : if (buffer->descriptor->SupportsTailCalls()) {
766 212 : frame_state = NodeProperties::GetFrameStateInput(frame_state);
767 : buffer->frame_state_descriptor =
768 424 : buffer->frame_state_descriptor->outer_state();
769 1412 : while (buffer->frame_state_descriptor != nullptr &&
770 : (buffer->frame_state_descriptor->type() ==
771 222 : FrameStateType::kArgumentsAdaptor ||
772 : buffer->frame_state_descriptor->type() ==
773 : FrameStateType::kTailCallerFunction)) {
774 188 : frame_state = NodeProperties::GetFrameStateInput(frame_state);
775 : buffer->frame_state_descriptor =
776 376 : buffer->frame_state_descriptor->outer_state();
777 : }
778 : }
779 :
780 : int const state_id = sequence()->AddDeoptimizationEntry(
781 : buffer->frame_state_descriptor, DeoptimizeKind::kEager,
782 4826844 : DeoptimizeReason::kNoReason);
783 4826861 : buffer->instruction_args.push_back(g.TempImmediate(state_id));
784 :
785 : StateObjectDeduplicator deduplicator(instruction_zone());
786 :
787 : frame_state_entries =
788 : 1 + AddInputsToFrameStateDescriptor(
789 : buffer->frame_state_descriptor, frame_state, &g, &deduplicator,
790 : &buffer->instruction_args, FrameStateInputKind::kStackSlot,
791 2413435 : instruction_zone());
792 :
793 : DCHECK_EQ(1 + frame_state_entries, buffer->instruction_args.size());
794 : }
795 :
796 : size_t input_count = static_cast<size_t>(buffer->input_count());
797 :
798 : // Split the arguments into pushed_nodes and instruction_args. Pushed
799 : // arguments require an explicit push instruction before the call and do
800 : // not appear as arguments to the call. Everything else ends up
801 : // as an InstructionOperand argument to the call.
802 3550132 : auto iter(call->inputs().begin());
803 : size_t pushed_count = 0;
804 3550132 : bool call_tail = (flags & kCallTail) != 0;
805 22862067 : for (size_t index = 0; index < input_count; ++iter, ++index) {
806 : DCHECK(iter != call->inputs().end());
807 : DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState);
808 22861996 : if (index == 0) continue; // The first argument (callee) is already done.
809 :
810 15761822 : LinkageLocation location = buffer->descriptor->GetInputLocation(index);
811 15761846 : if (call_tail) {
812 : location = LinkageLocation::ConvertToTailCallerLocation(
813 : location, stack_param_delta);
814 : }
815 15761846 : InstructionOperand op = g.UseLocation(*iter, location);
816 15761906 : if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) {
817 3687032 : int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1;
818 11061097 : if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
819 1531054 : buffer->pushed_nodes.resize(stack_index + 1);
820 : }
821 3687033 : PushParameter parameter(*iter, buffer->descriptor->GetInputType(index));
822 3687033 : buffer->pushed_nodes[stack_index] = parameter;
823 : pushed_count++;
824 : } else {
825 12074874 : buffer->instruction_args.push_back(op);
826 : }
827 : }
828 : DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count -
829 : frame_state_entries);
830 3550158 : if (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK && call_tail &&
831 3550158 : stack_param_delta != 0) {
832 : // For tail calls that change the size of their parameter list and keep
833 : // their return address on the stack, move the return address to just above
834 : // the parameters.
835 : LinkageLocation saved_return_location =
836 : LinkageLocation::ForSavedCallerReturnAddress();
837 : InstructionOperand return_address =
838 : g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation(
839 : saved_return_location, stack_param_delta),
840 12164 : saved_return_location);
841 12164 : buffer->instruction_args.push_back(return_address);
842 : }
843 3550158 : }
844 :
845 8326895 : bool InstructionSelector::IsSourcePositionUsed(Node* node) {
846 18919095 : return (source_position_mode_ == kAllSourcePositions ||
847 6165650 : node->opcode() == IrOpcode::kCall ||
848 16757194 : node->opcode() == IrOpcode::kTrapIf ||
849 0 : node->opcode() == IrOpcode::kTrapUnless);
850 : }
851 :
852 45847167 : void InstructionSelector::VisitBlock(BasicBlock* block) {
853 : DCHECK(!current_block_);
854 11461844 : current_block_ = block;
855 : auto current_num_instructions = [&] {
856 : DCHECK_GE(kMaxInt, instructions_.size());
857 148728672 : return static_cast<int>(instructions_.size());
858 11461844 : };
859 : int current_block_end = current_num_instructions();
860 :
861 : int effect_level = 0;
862 144087630 : for (Node* const node : *block) {
863 : SetEffectLevel(node, effect_level);
864 118827382 : if (node->opcode() == IrOpcode::kStore ||
865 58248659 : node->opcode() == IrOpcode::kUnalignedStore ||
866 58195701 : node->opcode() == IrOpcode::kCheckedStore ||
867 55025401 : node->opcode() == IrOpcode::kCall ||
868 115605940 : node->opcode() == IrOpcode::kProtectedLoad ||
869 : node->opcode() == IrOpcode::kProtectedStore) {
870 5559715 : ++effect_level;
871 : }
872 : }
873 :
874 : // We visit the control first, then the nodes in the block, so the block's
875 : // control input should be on the same effect level as the last node.
876 11461844 : if (block->control_input() != nullptr) {
877 : SetEffectLevel(block->control_input(), effect_level);
878 : }
879 :
880 37181658 : auto FinishEmittedInstructions = [&](Node* node, int instruction_start) {
881 41624554 : if (instruction_selection_failed()) return false;
882 74363716 : if (current_num_instructions() == instruction_start) return true;
883 : std::reverse(instructions_.begin() + instruction_start,
884 38568030 : instructions_.end());
885 34125134 : if (!node) return true;
886 28440648 : SourcePosition source_position = source_positions_->GetSourcePosition(node);
887 39032878 : if (source_position.IsKnown() && IsSourcePositionUsed(node)) {
888 4442896 : sequence()->SetSourcePosition(instructions_[instruction_start],
889 8885792 : source_position);
890 : }
891 : return true;
892 11461844 : };
893 :
894 : // Generate code for the block control "top down", but schedule the code
895 : // "bottom up".
896 11461844 : VisitControl(block);
897 11461714 : if (!FinishEmittedInstructions(block->control_input(), current_block_end))
898 0 : return;
899 :
900 : // Visit code in reverse control flow order, because architecture-specific
901 : // matching may cover more than one node at a time.
902 132626413 : for (auto node : base::Reversed(*block)) {
903 : // Skip nodes that are unused or already defined.
904 86418728 : if (!IsUsed(node) || IsDefined(node)) continue;
905 : // Generate code for this node "top down", but schedule the code "bottom
906 : // up".
907 : int current_node_end = current_num_instructions();
908 25720634 : VisitNode(node);
909 25720631 : if (!FinishEmittedInstructions(node, current_node_end)) return;
910 : }
911 :
912 : // We're done with the block.
913 : InstructionBlock* instruction_block =
914 11461765 : sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
915 22923478 : instruction_block->set_code_start(static_cast<int>(instructions_.size()));
916 : instruction_block->set_code_end(current_block_end);
917 :
918 11461739 : current_block_ = nullptr;
919 : }
920 :
921 :
922 11484970 : void InstructionSelector::VisitControl(BasicBlock* block) {
923 : #ifdef DEBUG
924 : // SSA deconstruction requires targets of branches not to have phis.
925 : // Edge split form guarantees this property, but is more strict.
926 : if (block->SuccessorCount() > 1) {
927 : for (BasicBlock* const successor : block->successors()) {
928 : for (Node* const node : *successor) {
929 : // If this CHECK fails, you might have specified merged variables
930 : // for a label with only one predecessor.
931 : CHECK(!IrOpcode::IsPhiOpcode(node->opcode()));
932 : }
933 : }
934 : }
935 : #endif
936 :
937 16280 : Node* input = block->control_input();
938 11461838 : switch (block->control()) {
939 : case BasicBlock::kGoto:
940 5684860 : return VisitGoto(block->SuccessorAt(0));
941 : case BasicBlock::kCall: {
942 : DCHECK_EQ(IrOpcode::kCall, input->opcode());
943 : BasicBlock* success = block->SuccessorAt(0);
944 : BasicBlock* exception = block->SuccessorAt(1);
945 231390 : return VisitCall(input, exception), VisitGoto(success);
946 : }
947 : case BasicBlock::kTailCall: {
948 : DCHECK_EQ(IrOpcode::kTailCall, input->opcode());
949 149226 : return VisitTailCall(input);
950 : }
951 : case BasicBlock::kBranch: {
952 : DCHECK_EQ(IrOpcode::kBranch, input->opcode());
953 : BasicBlock* tbranch = block->SuccessorAt(0);
954 : BasicBlock* fbranch = block->SuccessorAt(1);
955 3308771 : if (tbranch == fbranch) return VisitGoto(tbranch);
956 3308771 : return VisitBranch(input, tbranch, fbranch);
957 : }
958 : case BasicBlock::kSwitch: {
959 : DCHECK_EQ(IrOpcode::kSwitch, input->opcode());
960 : SwitchInfo sw;
961 : // Last successor must be Default.
962 23132 : sw.default_branch = block->successors().back();
963 : DCHECK_EQ(IrOpcode::kIfDefault, sw.default_branch->front()->opcode());
964 : // All other successors must be cases.
965 23132 : sw.case_count = block->SuccessorCount() - 1;
966 23132 : sw.case_branches = &block->successors().front();
967 : // Determine case values and their min/max.
968 23132 : sw.case_values = zone()->NewArray<int32_t>(sw.case_count);
969 23132 : sw.min_value = std::numeric_limits<int32_t>::max();
970 23132 : sw.max_value = std::numeric_limits<int32_t>::min();
971 168280 : for (size_t index = 0; index < sw.case_count; ++index) {
972 145148 : BasicBlock* branch = sw.case_branches[index];
973 145148 : int32_t value = OpParameter<int32_t>(branch->front()->op());
974 145148 : sw.case_values[index] = value;
975 145148 : if (sw.min_value > value) sw.min_value = value;
976 145148 : if (sw.max_value < value) sw.max_value = value;
977 : }
978 : DCHECK_LE(sw.min_value, sw.max_value);
979 : // Note that {value_range} can be 0 if {min_value} is -2^31 and
980 : // {max_value}
981 : // is 2^31-1, so don't assume that it's non-zero below.
982 23132 : sw.value_range = 1u + bit_cast<uint32_t>(sw.max_value) -
983 23132 : bit_cast<uint32_t>(sw.min_value);
984 23132 : return VisitSwitch(input, sw);
985 : }
986 : case BasicBlock::kReturn: {
987 : DCHECK_EQ(IrOpcode::kReturn, input->opcode());
988 1093942 : return VisitReturn(input);
989 : }
990 : case BasicBlock::kDeoptimize: {
991 16280 : DeoptimizeParameters p = DeoptimizeParametersOf(input->op());
992 : Node* value = input->InputAt(0);
993 : return VisitDeoptimize(p.kind(), p.reason(), value);
994 : }
995 : case BasicBlock::kThrow:
996 : DCHECK_EQ(IrOpcode::kThrow, input->opcode());
997 : return VisitThrow(input);
998 : case BasicBlock::kNone: {
999 : // Exit block doesn't have control.
1000 : DCHECK_NULL(input);
1001 : break;
1002 : }
1003 : default:
1004 0 : UNREACHABLE();
1005 : break;
1006 : }
1007 : }
1008 :
1009 0 : void InstructionSelector::MarkPairProjectionsAsWord32(Node* node) {
1010 0 : Node* projection0 = NodeProperties::FindProjection(node, 0);
1011 0 : if (projection0) {
1012 : MarkAsWord32(projection0);
1013 : }
1014 0 : Node* projection1 = NodeProperties::FindProjection(node, 1);
1015 0 : if (projection1) {
1016 : MarkAsWord32(projection1);
1017 : }
1018 0 : }
1019 :
1020 27511722 : void InstructionSelector::VisitNode(Node* node) {
1021 : DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes.
1022 25720672 : switch (node->opcode()) {
1023 : case IrOpcode::kStart:
1024 : case IrOpcode::kLoop:
1025 : case IrOpcode::kEnd:
1026 : case IrOpcode::kBranch:
1027 : case IrOpcode::kIfTrue:
1028 : case IrOpcode::kIfFalse:
1029 : case IrOpcode::kIfSuccess:
1030 : case IrOpcode::kSwitch:
1031 : case IrOpcode::kIfValue:
1032 : case IrOpcode::kIfDefault:
1033 : case IrOpcode::kEffectPhi:
1034 : case IrOpcode::kMerge:
1035 : case IrOpcode::kTerminate:
1036 : case IrOpcode::kBeginRegion:
1037 : // No code needed for these graph artifacts.
1038 : return;
1039 : case IrOpcode::kIfException:
1040 209287 : return MarkAsReference(node), VisitIfException(node);
1041 : case IrOpcode::kFinishRegion:
1042 : return MarkAsReference(node), VisitFinishRegion(node);
1043 : case IrOpcode::kParameter: {
1044 : MachineType type =
1045 3582130 : linkage()->GetParameterType(ParameterIndexOf(node->op()));
1046 1791086 : MarkAsRepresentation(type.representation(), node);
1047 1791092 : return VisitParameter(node);
1048 : }
1049 : case IrOpcode::kOsrValue:
1050 25895 : return MarkAsReference(node), VisitOsrValue(node);
1051 : case IrOpcode::kPhi: {
1052 1333566 : MachineRepresentation rep = PhiRepresentationOf(node->op());
1053 1333566 : if (rep == MachineRepresentation::kNone) return;
1054 1333569 : MarkAsRepresentation(rep, node);
1055 1333570 : return VisitPhi(node);
1056 : }
1057 : case IrOpcode::kProjection:
1058 330922 : return VisitProjection(node);
1059 : case IrOpcode::kInt32Constant:
1060 : case IrOpcode::kInt64Constant:
1061 : case IrOpcode::kExternalConstant:
1062 : case IrOpcode::kRelocatableInt32Constant:
1063 : case IrOpcode::kRelocatableInt64Constant:
1064 3659927 : return VisitConstant(node);
1065 : case IrOpcode::kFloat32Constant:
1066 8425 : return MarkAsFloat32(node), VisitConstant(node);
1067 : case IrOpcode::kFloat64Constant:
1068 238924 : return MarkAsFloat64(node), VisitConstant(node);
1069 : case IrOpcode::kHeapConstant:
1070 2915353 : return MarkAsReference(node), VisitConstant(node);
1071 : case IrOpcode::kNumberConstant: {
1072 2224509 : double value = OpParameter<double>(node);
1073 2224509 : if (!IsSmiDouble(value)) MarkAsReference(node);
1074 2224509 : return VisitConstant(node);
1075 : }
1076 : case IrOpcode::kCall:
1077 3169541 : return VisitCall(node);
1078 : case IrOpcode::kDeoptimizeIf:
1079 95921 : return VisitDeoptimizeIf(node);
1080 : case IrOpcode::kDeoptimizeUnless:
1081 170753 : return VisitDeoptimizeUnless(node);
1082 : case IrOpcode::kTrapIf:
1083 : return VisitTrapIf(node, static_cast<Runtime::FunctionId>(
1084 657 : OpParameter<int32_t>(node->op())));
1085 : case IrOpcode::kTrapUnless:
1086 : return VisitTrapUnless(node, static_cast<Runtime::FunctionId>(
1087 15640 : OpParameter<int32_t>(node->op())));
1088 : case IrOpcode::kFrameState:
1089 : case IrOpcode::kStateValues:
1090 : case IrOpcode::kObjectState:
1091 : return;
1092 : case IrOpcode::kDebugBreak:
1093 : VisitDebugBreak(node);
1094 : return;
1095 : case IrOpcode::kComment:
1096 0 : VisitComment(node);
1097 0 : return;
1098 : case IrOpcode::kRetain:
1099 6514 : VisitRetain(node);
1100 6514 : return;
1101 : case IrOpcode::kLoad: {
1102 2777328 : LoadRepresentation type = LoadRepresentationOf(node->op());
1103 2777329 : MarkAsRepresentation(type.representation(), node);
1104 2777331 : return VisitLoad(node);
1105 : }
1106 : case IrOpcode::kStore:
1107 2334400 : return VisitStore(node);
1108 : case IrOpcode::kProtectedStore:
1109 180 : return VisitProtectedStore(node);
1110 : case IrOpcode::kWord32And:
1111 84560 : return MarkAsWord32(node), VisitWord32And(node);
1112 : case IrOpcode::kWord32Or:
1113 13949 : return MarkAsWord32(node), VisitWord32Or(node);
1114 : case IrOpcode::kWord32Xor:
1115 13814 : return MarkAsWord32(node), VisitWord32Xor(node);
1116 : case IrOpcode::kWord32Shl:
1117 12367 : return MarkAsWord32(node), VisitWord32Shl(node);
1118 : case IrOpcode::kWord32Shr:
1119 35862 : return MarkAsWord32(node), VisitWord32Shr(node);
1120 : case IrOpcode::kWord32Sar:
1121 13542 : return MarkAsWord32(node), VisitWord32Sar(node);
1122 : case IrOpcode::kWord32Ror:
1123 933 : return MarkAsWord32(node), VisitWord32Ror(node);
1124 : case IrOpcode::kWord32Equal:
1125 36265 : return VisitWord32Equal(node);
1126 : case IrOpcode::kWord32Clz:
1127 849 : return MarkAsWord32(node), VisitWord32Clz(node);
1128 : case IrOpcode::kWord32Ctz:
1129 468 : return MarkAsWord32(node), VisitWord32Ctz(node);
1130 : case IrOpcode::kWord32ReverseBits:
1131 0 : return MarkAsWord32(node), VisitWord32ReverseBits(node);
1132 : case IrOpcode::kWord32ReverseBytes:
1133 0 : return MarkAsWord32(node), VisitWord32ReverseBytes(node);
1134 : case IrOpcode::kInt32AbsWithOverflow:
1135 0 : return MarkAsWord32(node), VisitInt32AbsWithOverflow(node);
1136 : case IrOpcode::kWord32Popcnt:
1137 98 : return MarkAsWord32(node), VisitWord32Popcnt(node);
1138 : case IrOpcode::kWord64Popcnt:
1139 35 : return MarkAsWord32(node), VisitWord64Popcnt(node);
1140 : case IrOpcode::kWord64And:
1141 139328 : return MarkAsWord64(node), VisitWord64And(node);
1142 : case IrOpcode::kWord64Or:
1143 17920 : return MarkAsWord64(node), VisitWord64Or(node);
1144 : case IrOpcode::kWord64Xor:
1145 454 : return MarkAsWord64(node), VisitWord64Xor(node);
1146 : case IrOpcode::kWord64Shl:
1147 282571 : return MarkAsWord64(node), VisitWord64Shl(node);
1148 : case IrOpcode::kWord64Shr:
1149 98915 : return MarkAsWord64(node), VisitWord64Shr(node);
1150 : case IrOpcode::kWord64Sar:
1151 46646 : return MarkAsWord64(node), VisitWord64Sar(node);
1152 : case IrOpcode::kWord64Ror:
1153 70 : return MarkAsWord64(node), VisitWord64Ror(node);
1154 : case IrOpcode::kWord64Clz:
1155 28 : return MarkAsWord64(node), VisitWord64Clz(node);
1156 : case IrOpcode::kWord64Ctz:
1157 13 : return MarkAsWord64(node), VisitWord64Ctz(node);
1158 : case IrOpcode::kWord64ReverseBits:
1159 0 : return MarkAsWord64(node), VisitWord64ReverseBits(node);
1160 : case IrOpcode::kWord64ReverseBytes:
1161 0 : return MarkAsWord64(node), VisitWord64ReverseBytes(node);
1162 : case IrOpcode::kInt64AbsWithOverflow:
1163 0 : return MarkAsWord64(node), VisitInt64AbsWithOverflow(node);
1164 : case IrOpcode::kWord64Equal:
1165 27433 : return VisitWord64Equal(node);
1166 : case IrOpcode::kInt32Add:
1167 193755 : return MarkAsWord32(node), VisitInt32Add(node);
1168 : case IrOpcode::kInt32AddWithOverflow:
1169 18150 : return MarkAsWord32(node), VisitInt32AddWithOverflow(node);
1170 : case IrOpcode::kInt32Sub:
1171 28279 : return MarkAsWord32(node), VisitInt32Sub(node);
1172 : case IrOpcode::kInt32SubWithOverflow:
1173 18150 : return VisitInt32SubWithOverflow(node);
1174 : case IrOpcode::kInt32Mul:
1175 35249 : return MarkAsWord32(node), VisitInt32Mul(node);
1176 : case IrOpcode::kInt32MulWithOverflow:
1177 18150 : return MarkAsWord32(node), VisitInt32MulWithOverflow(node);
1178 : case IrOpcode::kInt32MulHigh:
1179 5418 : return VisitInt32MulHigh(node);
1180 : case IrOpcode::kInt32Div:
1181 1016 : return MarkAsWord32(node), VisitInt32Div(node);
1182 : case IrOpcode::kInt32Mod:
1183 1748 : return MarkAsWord32(node), VisitInt32Mod(node);
1184 : case IrOpcode::kInt32LessThan:
1185 1827 : return VisitInt32LessThan(node);
1186 : case IrOpcode::kInt32LessThanOrEqual:
1187 1199 : return VisitInt32LessThanOrEqual(node);
1188 : case IrOpcode::kUint32Div:
1189 558 : return MarkAsWord32(node), VisitUint32Div(node);
1190 : case IrOpcode::kUint32LessThan:
1191 2506 : return VisitUint32LessThan(node);
1192 : case IrOpcode::kUint32LessThanOrEqual:
1193 3734 : return VisitUint32LessThanOrEqual(node);
1194 : case IrOpcode::kUint32Mod:
1195 530 : return MarkAsWord32(node), VisitUint32Mod(node);
1196 : case IrOpcode::kUint32MulHigh:
1197 857 : return VisitUint32MulHigh(node);
1198 : case IrOpcode::kInt64Add:
1199 1018442 : return MarkAsWord64(node), VisitInt64Add(node);
1200 : case IrOpcode::kInt64AddWithOverflow:
1201 36504 : return MarkAsWord64(node), VisitInt64AddWithOverflow(node);
1202 : case IrOpcode::kInt64Sub:
1203 28926 : return MarkAsWord64(node), VisitInt64Sub(node);
1204 : case IrOpcode::kInt64SubWithOverflow:
1205 36504 : return MarkAsWord64(node), VisitInt64SubWithOverflow(node);
1206 : case IrOpcode::kInt64Mul:
1207 4157 : return MarkAsWord64(node), VisitInt64Mul(node);
1208 : case IrOpcode::kInt64Div:
1209 482 : return MarkAsWord64(node), VisitInt64Div(node);
1210 : case IrOpcode::kInt64Mod:
1211 412 : return MarkAsWord64(node), VisitInt64Mod(node);
1212 : case IrOpcode::kInt64LessThan:
1213 577 : return VisitInt64LessThan(node);
1214 : case IrOpcode::kInt64LessThanOrEqual:
1215 533 : return VisitInt64LessThanOrEqual(node);
1216 : case IrOpcode::kUint64Div:
1217 412 : return MarkAsWord64(node), VisitUint64Div(node);
1218 : case IrOpcode::kUint64LessThan:
1219 427 : return VisitUint64LessThan(node);
1220 : case IrOpcode::kUint64LessThanOrEqual:
1221 426 : return VisitUint64LessThanOrEqual(node);
1222 : case IrOpcode::kUint64Mod:
1223 412 : return MarkAsWord64(node), VisitUint64Mod(node);
1224 : case IrOpcode::kBitcastTaggedToWord:
1225 0 : return MarkAsRepresentation(MachineType::PointerRepresentation(), node),
1226 : VisitBitcastTaggedToWord(node);
1227 : case IrOpcode::kBitcastWordToTagged:
1228 239211 : return MarkAsReference(node), VisitBitcastWordToTagged(node);
1229 : case IrOpcode::kBitcastWordToTaggedSigned:
1230 0 : return MarkAsRepresentation(MachineRepresentation::kTaggedSigned, node),
1231 0 : EmitIdentity(node);
1232 : case IrOpcode::kChangeFloat32ToFloat64:
1233 11259 : return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node);
1234 : case IrOpcode::kChangeInt32ToFloat64:
1235 249969 : return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node);
1236 : case IrOpcode::kChangeUint32ToFloat64:
1237 2002 : return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node);
1238 : case IrOpcode::kChangeFloat64ToInt32:
1239 6689 : return MarkAsWord32(node), VisitChangeFloat64ToInt32(node);
1240 : case IrOpcode::kChangeFloat64ToUint32:
1241 421 : return MarkAsWord32(node), VisitChangeFloat64ToUint32(node);
1242 : case IrOpcode::kChangeFloat64ToUint64:
1243 129 : return MarkAsWord64(node), VisitChangeFloat64ToUint64(node);
1244 : case IrOpcode::kFloat64SilenceNaN:
1245 : MarkAsFloat64(node);
1246 2007 : if (CanProduceSignalingNaN(node->InputAt(0))) {
1247 1765 : return VisitFloat64SilenceNaN(node);
1248 : } else {
1249 242 : return EmitIdentity(node);
1250 : }
1251 : case IrOpcode::kTruncateFloat64ToUint32:
1252 7 : return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node);
1253 : case IrOpcode::kTruncateFloat32ToInt32:
1254 132 : return MarkAsWord32(node), VisitTruncateFloat32ToInt32(node);
1255 : case IrOpcode::kTruncateFloat32ToUint32:
1256 13 : return MarkAsWord32(node), VisitTruncateFloat32ToUint32(node);
1257 : case IrOpcode::kTryTruncateFloat32ToInt64:
1258 26 : return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node);
1259 : case IrOpcode::kTryTruncateFloat64ToInt64:
1260 49 : return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node);
1261 : case IrOpcode::kTryTruncateFloat32ToUint64:
1262 26 : return MarkAsWord64(node), VisitTryTruncateFloat32ToUint64(node);
1263 : case IrOpcode::kTryTruncateFloat64ToUint64:
1264 26 : return MarkAsWord64(node), VisitTryTruncateFloat64ToUint64(node);
1265 : case IrOpcode::kChangeInt32ToInt64:
1266 66903 : return MarkAsWord64(node), VisitChangeInt32ToInt64(node);
1267 : case IrOpcode::kChangeUint32ToUint64:
1268 78216 : return MarkAsWord64(node), VisitChangeUint32ToUint64(node);
1269 : case IrOpcode::kTruncateFloat64ToFloat32:
1270 8039 : return MarkAsFloat32(node), VisitTruncateFloat64ToFloat32(node);
1271 : case IrOpcode::kTruncateFloat64ToWord32:
1272 70367 : return MarkAsWord32(node), VisitTruncateFloat64ToWord32(node);
1273 : case IrOpcode::kTruncateInt64ToInt32:
1274 279134 : return MarkAsWord32(node), VisitTruncateInt64ToInt32(node);
1275 : case IrOpcode::kRoundFloat64ToInt32:
1276 76349 : return MarkAsWord32(node), VisitRoundFloat64ToInt32(node);
1277 : case IrOpcode::kRoundInt64ToFloat32:
1278 13 : return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node);
1279 : case IrOpcode::kRoundInt32ToFloat32:
1280 309 : return MarkAsFloat32(node), VisitRoundInt32ToFloat32(node);
1281 : case IrOpcode::kRoundInt64ToFloat64:
1282 759 : return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node);
1283 : case IrOpcode::kBitcastFloat32ToInt32:
1284 114 : return MarkAsWord32(node), VisitBitcastFloat32ToInt32(node);
1285 : case IrOpcode::kRoundUint32ToFloat32:
1286 37 : return MarkAsFloat32(node), VisitRoundUint32ToFloat32(node);
1287 : case IrOpcode::kRoundUint64ToFloat32:
1288 13 : return MarkAsFloat64(node), VisitRoundUint64ToFloat32(node);
1289 : case IrOpcode::kRoundUint64ToFloat64:
1290 13 : return MarkAsFloat64(node), VisitRoundUint64ToFloat64(node);
1291 : case IrOpcode::kBitcastFloat64ToInt64:
1292 257 : return MarkAsWord64(node), VisitBitcastFloat64ToInt64(node);
1293 : case IrOpcode::kBitcastInt32ToFloat32:
1294 52 : return MarkAsFloat32(node), VisitBitcastInt32ToFloat32(node);
1295 : case IrOpcode::kBitcastInt64ToFloat64:
1296 131 : return MarkAsFloat64(node), VisitBitcastInt64ToFloat64(node);
1297 : case IrOpcode::kFloat32Add:
1298 118 : return MarkAsFloat32(node), VisitFloat32Add(node);
1299 : case IrOpcode::kFloat32Sub:
1300 1456 : return MarkAsFloat32(node), VisitFloat32Sub(node);
1301 : case IrOpcode::kFloat32Neg:
1302 28 : return MarkAsFloat32(node), VisitFloat32Neg(node);
1303 : case IrOpcode::kFloat32Mul:
1304 47 : return MarkAsFloat32(node), VisitFloat32Mul(node);
1305 : case IrOpcode::kFloat32Div:
1306 44 : return MarkAsFloat32(node), VisitFloat32Div(node);
1307 : case IrOpcode::kFloat32Abs:
1308 52 : return MarkAsFloat32(node), VisitFloat32Abs(node);
1309 : case IrOpcode::kFloat32Sqrt:
1310 30 : return MarkAsFloat32(node), VisitFloat32Sqrt(node);
1311 : case IrOpcode::kFloat32Equal:
1312 121 : return VisitFloat32Equal(node);
1313 : case IrOpcode::kFloat32LessThan:
1314 59 : return VisitFloat32LessThan(node);
1315 : case IrOpcode::kFloat32LessThanOrEqual:
1316 49 : return VisitFloat32LessThanOrEqual(node);
1317 : case IrOpcode::kFloat32Max:
1318 29 : return MarkAsFloat32(node), VisitFloat32Max(node);
1319 : case IrOpcode::kFloat32Min:
1320 29 : return MarkAsFloat32(node), VisitFloat32Min(node);
1321 : case IrOpcode::kFloat64Add:
1322 54725 : return MarkAsFloat64(node), VisitFloat64Add(node);
1323 : case IrOpcode::kFloat64Sub:
1324 25324 : return MarkAsFloat64(node), VisitFloat64Sub(node);
1325 : case IrOpcode::kFloat64Neg:
1326 9815 : return MarkAsFloat64(node), VisitFloat64Neg(node);
1327 : case IrOpcode::kFloat64Mul:
1328 15570 : return MarkAsFloat64(node), VisitFloat64Mul(node);
1329 : case IrOpcode::kFloat64Div:
1330 12521 : return MarkAsFloat64(node), VisitFloat64Div(node);
1331 : case IrOpcode::kFloat64Mod:
1332 1022 : return MarkAsFloat64(node), VisitFloat64Mod(node);
1333 : case IrOpcode::kFloat64Min:
1334 153 : return MarkAsFloat64(node), VisitFloat64Min(node);
1335 : case IrOpcode::kFloat64Max:
1336 97 : return MarkAsFloat64(node), VisitFloat64Max(node);
1337 : case IrOpcode::kFloat64Abs:
1338 245 : return MarkAsFloat64(node), VisitFloat64Abs(node);
1339 : case IrOpcode::kFloat64Acos:
1340 : return MarkAsFloat64(node), VisitFloat64Acos(node);
1341 : case IrOpcode::kFloat64Acosh:
1342 : return MarkAsFloat64(node), VisitFloat64Acosh(node);
1343 : case IrOpcode::kFloat64Asin:
1344 : return MarkAsFloat64(node), VisitFloat64Asin(node);
1345 : case IrOpcode::kFloat64Asinh:
1346 : return MarkAsFloat64(node), VisitFloat64Asinh(node);
1347 : case IrOpcode::kFloat64Atan:
1348 : return MarkAsFloat64(node), VisitFloat64Atan(node);
1349 : case IrOpcode::kFloat64Atanh:
1350 : return MarkAsFloat64(node), VisitFloat64Atanh(node);
1351 : case IrOpcode::kFloat64Atan2:
1352 : return MarkAsFloat64(node), VisitFloat64Atan2(node);
1353 : case IrOpcode::kFloat64Cbrt:
1354 : return MarkAsFloat64(node), VisitFloat64Cbrt(node);
1355 : case IrOpcode::kFloat64Cos:
1356 : return MarkAsFloat64(node), VisitFloat64Cos(node);
1357 : case IrOpcode::kFloat64Cosh:
1358 : return MarkAsFloat64(node), VisitFloat64Cosh(node);
1359 : case IrOpcode::kFloat64Exp:
1360 : return MarkAsFloat64(node), VisitFloat64Exp(node);
1361 : case IrOpcode::kFloat64Expm1:
1362 : return MarkAsFloat64(node), VisitFloat64Expm1(node);
1363 : case IrOpcode::kFloat64Log:
1364 : return MarkAsFloat64(node), VisitFloat64Log(node);
1365 : case IrOpcode::kFloat64Log1p:
1366 : return MarkAsFloat64(node), VisitFloat64Log1p(node);
1367 : case IrOpcode::kFloat64Log10:
1368 : return MarkAsFloat64(node), VisitFloat64Log10(node);
1369 : case IrOpcode::kFloat64Log2:
1370 : return MarkAsFloat64(node), VisitFloat64Log2(node);
1371 : case IrOpcode::kFloat64Pow:
1372 : return MarkAsFloat64(node), VisitFloat64Pow(node);
1373 : case IrOpcode::kFloat64Sin:
1374 : return MarkAsFloat64(node), VisitFloat64Sin(node);
1375 : case IrOpcode::kFloat64Sinh:
1376 : return MarkAsFloat64(node), VisitFloat64Sinh(node);
1377 : case IrOpcode::kFloat64Sqrt:
1378 258 : return MarkAsFloat64(node), VisitFloat64Sqrt(node);
1379 : case IrOpcode::kFloat64Tan:
1380 : return MarkAsFloat64(node), VisitFloat64Tan(node);
1381 : case IrOpcode::kFloat64Tanh:
1382 : return MarkAsFloat64(node), VisitFloat64Tanh(node);
1383 : case IrOpcode::kFloat64Equal:
1384 5913 : return VisitFloat64Equal(node);
1385 : case IrOpcode::kFloat64LessThan:
1386 7359 : return VisitFloat64LessThan(node);
1387 : case IrOpcode::kFloat64LessThanOrEqual:
1388 1445 : return VisitFloat64LessThanOrEqual(node);
1389 : case IrOpcode::kFloat32RoundDown:
1390 40 : return MarkAsFloat32(node), VisitFloat32RoundDown(node);
1391 : case IrOpcode::kFloat64RoundDown:
1392 9016 : return MarkAsFloat64(node), VisitFloat64RoundDown(node);
1393 : case IrOpcode::kFloat32RoundUp:
1394 40 : return MarkAsFloat32(node), VisitFloat32RoundUp(node);
1395 : case IrOpcode::kFloat64RoundUp:
1396 5897 : return MarkAsFloat64(node), VisitFloat64RoundUp(node);
1397 : case IrOpcode::kFloat32RoundTruncate:
1398 146 : return MarkAsFloat32(node), VisitFloat32RoundTruncate(node);
1399 : case IrOpcode::kFloat64RoundTruncate:
1400 3147 : return MarkAsFloat64(node), VisitFloat64RoundTruncate(node);
1401 : case IrOpcode::kFloat64RoundTiesAway:
1402 0 : return MarkAsFloat64(node), VisitFloat64RoundTiesAway(node);
1403 : case IrOpcode::kFloat32RoundTiesEven:
1404 13 : return MarkAsFloat32(node), VisitFloat32RoundTiesEven(node);
1405 : case IrOpcode::kFloat64RoundTiesEven:
1406 436 : return MarkAsFloat64(node), VisitFloat64RoundTiesEven(node);
1407 : case IrOpcode::kFloat64ExtractLowWord32:
1408 6 : return MarkAsWord32(node), VisitFloat64ExtractLowWord32(node);
1409 : case IrOpcode::kFloat64ExtractHighWord32:
1410 44203 : return MarkAsWord32(node), VisitFloat64ExtractHighWord32(node);
1411 : case IrOpcode::kFloat64InsertLowWord32:
1412 6 : return MarkAsFloat64(node), VisitFloat64InsertLowWord32(node);
1413 : case IrOpcode::kFloat64InsertHighWord32:
1414 6 : return MarkAsFloat64(node), VisitFloat64InsertHighWord32(node);
1415 : case IrOpcode::kStackSlot:
1416 1418 : return VisitStackSlot(node);
1417 : case IrOpcode::kLoadStackPointer:
1418 43 : return VisitLoadStackPointer(node);
1419 : case IrOpcode::kLoadFramePointer:
1420 4808 : return VisitLoadFramePointer(node);
1421 : case IrOpcode::kLoadParentFramePointer:
1422 53041 : return VisitLoadParentFramePointer(node);
1423 : case IrOpcode::kUnalignedLoad: {
1424 : UnalignedLoadRepresentation type =
1425 0 : UnalignedLoadRepresentationOf(node->op());
1426 0 : MarkAsRepresentation(type.representation(), node);
1427 0 : return VisitUnalignedLoad(node);
1428 : }
1429 : case IrOpcode::kUnalignedStore:
1430 0 : return VisitUnalignedStore(node);
1431 : case IrOpcode::kCheckedLoad: {
1432 : MachineRepresentation rep =
1433 74190 : CheckedLoadRepresentationOf(node->op()).representation();
1434 74190 : MarkAsRepresentation(rep, node);
1435 74190 : return VisitCheckedLoad(node);
1436 : }
1437 : case IrOpcode::kCheckedStore:
1438 53151 : return VisitCheckedStore(node);
1439 : case IrOpcode::kInt32PairAdd:
1440 : MarkAsWord32(node);
1441 0 : MarkPairProjectionsAsWord32(node);
1442 0 : return VisitInt32PairAdd(node);
1443 : case IrOpcode::kInt32PairSub:
1444 : MarkAsWord32(node);
1445 0 : MarkPairProjectionsAsWord32(node);
1446 0 : return VisitInt32PairSub(node);
1447 : case IrOpcode::kInt32PairMul:
1448 : MarkAsWord32(node);
1449 0 : MarkPairProjectionsAsWord32(node);
1450 0 : return VisitInt32PairMul(node);
1451 : case IrOpcode::kWord32PairShl:
1452 : MarkAsWord32(node);
1453 0 : MarkPairProjectionsAsWord32(node);
1454 0 : return VisitWord32PairShl(node);
1455 : case IrOpcode::kWord32PairShr:
1456 : MarkAsWord32(node);
1457 0 : MarkPairProjectionsAsWord32(node);
1458 0 : return VisitWord32PairShr(node);
1459 : case IrOpcode::kWord32PairSar:
1460 : MarkAsWord32(node);
1461 0 : MarkPairProjectionsAsWord32(node);
1462 0 : return VisitWord32PairSar(node);
1463 : case IrOpcode::kAtomicLoad: {
1464 258 : LoadRepresentation type = LoadRepresentationOf(node->op());
1465 258 : MarkAsRepresentation(type.representation(), node);
1466 258 : return VisitAtomicLoad(node);
1467 : }
1468 : case IrOpcode::kAtomicStore:
1469 129 : return VisitAtomicStore(node);
1470 : #define ATOMIC_CASE(name) \
1471 : case IrOpcode::kAtomic##name: { \
1472 : MachineType type = AtomicOpRepresentationOf(node->op()); \
1473 : MarkAsRepresentation(type.representation(), node); \
1474 : return VisitAtomic##name(node); \
1475 : }
1476 258 : ATOMIC_CASE(Exchange)
1477 258 : ATOMIC_CASE(CompareExchange)
1478 258 : ATOMIC_CASE(Add)
1479 258 : ATOMIC_CASE(Sub)
1480 258 : ATOMIC_CASE(And)
1481 258 : ATOMIC_CASE(Or)
1482 258 : ATOMIC_CASE(Xor)
1483 : #undef ATOMIC_CASE
1484 : case IrOpcode::kProtectedLoad: {
1485 1470 : LoadRepresentation type = LoadRepresentationOf(node->op());
1486 1470 : MarkAsRepresentation(type.representation(), node);
1487 1470 : return VisitProtectedLoad(node);
1488 : }
1489 : case IrOpcode::kUnsafePointerAdd:
1490 3661 : MarkAsRepresentation(MachineType::PointerRepresentation(), node);
1491 : return VisitUnsafePointerAdd(node);
1492 : case IrOpcode::kF32x4Splat:
1493 0 : return MarkAsSimd128(node), VisitF32x4Splat(node);
1494 : case IrOpcode::kF32x4ExtractLane:
1495 0 : return MarkAsFloat32(node), VisitF32x4ExtractLane(node);
1496 : case IrOpcode::kF32x4ReplaceLane:
1497 0 : return MarkAsSimd128(node), VisitF32x4ReplaceLane(node);
1498 : case IrOpcode::kF32x4SConvertI32x4:
1499 0 : return MarkAsSimd128(node), VisitF32x4SConvertI32x4(node);
1500 : case IrOpcode::kF32x4UConvertI32x4:
1501 0 : return MarkAsSimd128(node), VisitF32x4UConvertI32x4(node);
1502 : case IrOpcode::kF32x4Abs:
1503 0 : return MarkAsSimd128(node), VisitF32x4Abs(node);
1504 : case IrOpcode::kF32x4Neg:
1505 0 : return MarkAsSimd128(node), VisitF32x4Neg(node);
1506 : case IrOpcode::kF32x4RecipApprox:
1507 0 : return MarkAsSimd128(node), VisitF32x4RecipApprox(node);
1508 : case IrOpcode::kF32x4RecipSqrtApprox:
1509 0 : return MarkAsSimd128(node), VisitF32x4RecipSqrtApprox(node);
1510 : case IrOpcode::kF32x4Add:
1511 0 : return MarkAsSimd128(node), VisitF32x4Add(node);
1512 : case IrOpcode::kF32x4AddHoriz:
1513 0 : return MarkAsSimd128(node), VisitF32x4AddHoriz(node);
1514 : case IrOpcode::kF32x4Sub:
1515 0 : return MarkAsSimd128(node), VisitF32x4Sub(node);
1516 : case IrOpcode::kF32x4Mul:
1517 0 : return MarkAsSimd128(node), VisitF32x4Mul(node);
1518 : case IrOpcode::kF32x4Min:
1519 0 : return MarkAsSimd128(node), VisitF32x4Min(node);
1520 : case IrOpcode::kF32x4Max:
1521 0 : return MarkAsSimd128(node), VisitF32x4Max(node);
1522 : case IrOpcode::kF32x4Eq:
1523 0 : return MarkAsSimd1x4(node), VisitF32x4Eq(node);
1524 : case IrOpcode::kF32x4Ne:
1525 0 : return MarkAsSimd1x4(node), VisitF32x4Ne(node);
1526 : case IrOpcode::kF32x4Lt:
1527 0 : return MarkAsSimd1x4(node), VisitF32x4Lt(node);
1528 : case IrOpcode::kF32x4Le:
1529 0 : return MarkAsSimd1x4(node), VisitF32x4Le(node);
1530 : case IrOpcode::kI32x4Splat:
1531 210 : return MarkAsSimd128(node), VisitI32x4Splat(node);
1532 : case IrOpcode::kI32x4ExtractLane:
1533 504 : return MarkAsWord32(node), VisitI32x4ExtractLane(node);
1534 : case IrOpcode::kI32x4ReplaceLane:
1535 42 : return MarkAsSimd128(node), VisitI32x4ReplaceLane(node);
1536 : case IrOpcode::kI32x4SConvertF32x4:
1537 0 : return MarkAsSimd128(node), VisitI32x4SConvertF32x4(node);
1538 : case IrOpcode::kI32x4SConvertI16x8Low:
1539 0 : return MarkAsSimd128(node), VisitI32x4SConvertI16x8Low(node);
1540 : case IrOpcode::kI32x4SConvertI16x8High:
1541 0 : return MarkAsSimd128(node), VisitI32x4SConvertI16x8High(node);
1542 : case IrOpcode::kI32x4Neg:
1543 0 : return MarkAsSimd128(node), VisitI32x4Neg(node);
1544 : case IrOpcode::kI32x4Shl:
1545 7 : return MarkAsSimd128(node), VisitI32x4Shl(node);
1546 : case IrOpcode::kI32x4ShrS:
1547 7 : return MarkAsSimd128(node), VisitI32x4ShrS(node);
1548 : case IrOpcode::kI32x4Add:
1549 7 : return MarkAsSimd128(node), VisitI32x4Add(node);
1550 : case IrOpcode::kI32x4AddHoriz:
1551 0 : return MarkAsSimd128(node), VisitI32x4AddHoriz(node);
1552 : case IrOpcode::kI32x4Sub:
1553 7 : return MarkAsSimd128(node), VisitI32x4Sub(node);
1554 : case IrOpcode::kI32x4Mul:
1555 7 : return MarkAsSimd128(node), VisitI32x4Mul(node);
1556 : case IrOpcode::kI32x4MinS:
1557 7 : return MarkAsSimd128(node), VisitI32x4MinS(node);
1558 : case IrOpcode::kI32x4MaxS:
1559 7 : return MarkAsSimd128(node), VisitI32x4MaxS(node);
1560 : case IrOpcode::kI32x4Eq:
1561 7 : return MarkAsSimd1x4(node), VisitI32x4Eq(node);
1562 : case IrOpcode::kI32x4Ne:
1563 14 : return MarkAsSimd1x4(node), VisitI32x4Ne(node);
1564 : case IrOpcode::kI32x4LtS:
1565 0 : return MarkAsSimd1x4(node), VisitI32x4LtS(node);
1566 : case IrOpcode::kI32x4LeS:
1567 0 : return MarkAsSimd1x4(node), VisitI32x4LeS(node);
1568 : case IrOpcode::kI32x4UConvertF32x4:
1569 0 : return MarkAsSimd128(node), VisitI32x4UConvertF32x4(node);
1570 : case IrOpcode::kI32x4UConvertI16x8Low:
1571 0 : return MarkAsSimd128(node), VisitI32x4UConvertI16x8Low(node);
1572 : case IrOpcode::kI32x4UConvertI16x8High:
1573 0 : return MarkAsSimd128(node), VisitI32x4UConvertI16x8High(node);
1574 : case IrOpcode::kI32x4ShrU:
1575 7 : return MarkAsSimd128(node), VisitI32x4ShrU(node);
1576 : case IrOpcode::kI32x4MinU:
1577 7 : return MarkAsSimd128(node), VisitI32x4MinU(node);
1578 : case IrOpcode::kI32x4MaxU:
1579 7 : return MarkAsSimd128(node), VisitI32x4MaxU(node);
1580 : case IrOpcode::kI32x4LtU:
1581 0 : return MarkAsSimd1x4(node), VisitI32x4LtU(node);
1582 : case IrOpcode::kI32x4LeU:
1583 0 : return MarkAsSimd1x4(node), VisitI32x4LeU(node);
1584 : case IrOpcode::kI16x8Splat:
1585 266 : return MarkAsSimd128(node), VisitI16x8Splat(node);
1586 : case IrOpcode::kI16x8ExtractLane:
1587 1428 : return MarkAsWord32(node), VisitI16x8ExtractLane(node);
1588 : case IrOpcode::kI16x8ReplaceLane:
1589 70 : return MarkAsSimd128(node), VisitI16x8ReplaceLane(node);
1590 : case IrOpcode::kI16x8SConvertI8x16Low:
1591 0 : return MarkAsSimd128(node), VisitI16x8SConvertI8x16Low(node);
1592 : case IrOpcode::kI16x8SConvertI8x16High:
1593 0 : return MarkAsSimd128(node), VisitI16x8SConvertI8x16High(node);
1594 : case IrOpcode::kI16x8Neg:
1595 0 : return MarkAsSimd128(node), VisitI16x8Neg(node);
1596 : case IrOpcode::kI16x8Shl:
1597 7 : return MarkAsSimd128(node), VisitI16x8Shl(node);
1598 : case IrOpcode::kI16x8ShrS:
1599 7 : return MarkAsSimd128(node), VisitI16x8ShrS(node);
1600 : case IrOpcode::kI16x8SConvertI32x4:
1601 0 : return MarkAsSimd128(node), VisitI16x8SConvertI32x4(node);
1602 : case IrOpcode::kI16x8Add:
1603 7 : return MarkAsSimd128(node), VisitI16x8Add(node);
1604 : case IrOpcode::kI16x8AddSaturateS:
1605 7 : return MarkAsSimd128(node), VisitI16x8AddSaturateS(node);
1606 : case IrOpcode::kI16x8AddHoriz:
1607 0 : return MarkAsSimd128(node), VisitI16x8AddHoriz(node);
1608 : case IrOpcode::kI16x8Sub:
1609 7 : return MarkAsSimd128(node), VisitI16x8Sub(node);
1610 : case IrOpcode::kI16x8SubSaturateS:
1611 7 : return MarkAsSimd128(node), VisitI16x8SubSaturateS(node);
1612 : case IrOpcode::kI16x8Mul:
1613 7 : return MarkAsSimd128(node), VisitI16x8Mul(node);
1614 : case IrOpcode::kI16x8MinS:
1615 7 : return MarkAsSimd128(node), VisitI16x8MinS(node);
1616 : case IrOpcode::kI16x8MaxS:
1617 7 : return MarkAsSimd128(node), VisitI16x8MaxS(node);
1618 : case IrOpcode::kI16x8Eq:
1619 7 : return MarkAsSimd1x8(node), VisitI16x8Eq(node);
1620 : case IrOpcode::kI16x8Ne:
1621 14 : return MarkAsSimd1x8(node), VisitI16x8Ne(node);
1622 : case IrOpcode::kI16x8LtS:
1623 0 : return MarkAsSimd1x8(node), VisitI16x8LtS(node);
1624 : case IrOpcode::kI16x8LeS:
1625 0 : return MarkAsSimd1x8(node), VisitI16x8LeS(node);
1626 : case IrOpcode::kI16x8UConvertI8x16Low:
1627 0 : return MarkAsSimd128(node), VisitI16x8UConvertI8x16Low(node);
1628 : case IrOpcode::kI16x8UConvertI8x16High:
1629 0 : return MarkAsSimd128(node), VisitI16x8UConvertI8x16High(node);
1630 : case IrOpcode::kI16x8ShrU:
1631 7 : return MarkAsSimd128(node), VisitI16x8ShrU(node);
1632 : case IrOpcode::kI16x8UConvertI32x4:
1633 0 : return MarkAsSimd128(node), VisitI16x8UConvertI32x4(node);
1634 : case IrOpcode::kI16x8AddSaturateU:
1635 7 : return MarkAsSimd128(node), VisitI16x8AddSaturateU(node);
1636 : case IrOpcode::kI16x8SubSaturateU:
1637 7 : return MarkAsSimd128(node), VisitI16x8SubSaturateU(node);
1638 : case IrOpcode::kI16x8MinU:
1639 7 : return MarkAsSimd128(node), VisitI16x8MinU(node);
1640 : case IrOpcode::kI16x8MaxU:
1641 7 : return MarkAsSimd128(node), VisitI16x8MaxU(node);
1642 : case IrOpcode::kI16x8LtU:
1643 0 : return MarkAsSimd1x8(node), VisitI16x8LtU(node);
1644 : case IrOpcode::kI16x8LeU:
1645 0 : return MarkAsSimd1x8(node), VisitI16x8LeU(node);
1646 : case IrOpcode::kI8x16Splat:
1647 231 : return MarkAsSimd128(node), VisitI8x16Splat(node);
1648 : case IrOpcode::kI8x16ExtractLane:
1649 3220 : return MarkAsWord32(node), VisitI8x16ExtractLane(node);
1650 : case IrOpcode::kI8x16ReplaceLane:
1651 126 : return MarkAsSimd128(node), VisitI8x16ReplaceLane(node);
1652 : case IrOpcode::kI8x16Neg:
1653 0 : return MarkAsSimd128(node), VisitI8x16Neg(node);
1654 : case IrOpcode::kI8x16Shl:
1655 0 : return MarkAsSimd128(node), VisitI8x16Shl(node);
1656 : case IrOpcode::kI8x16ShrS:
1657 0 : return MarkAsSimd128(node), VisitI8x16ShrS(node);
1658 : case IrOpcode::kI8x16SConvertI16x8:
1659 0 : return MarkAsSimd128(node), VisitI8x16SConvertI16x8(node);
1660 : case IrOpcode::kI8x16Add:
1661 7 : return MarkAsSimd128(node), VisitI8x16Add(node);
1662 : case IrOpcode::kI8x16AddSaturateS:
1663 7 : return MarkAsSimd128(node), VisitI8x16AddSaturateS(node);
1664 : case IrOpcode::kI8x16Sub:
1665 7 : return MarkAsSimd128(node), VisitI8x16Sub(node);
1666 : case IrOpcode::kI8x16SubSaturateS:
1667 7 : return MarkAsSimd128(node), VisitI8x16SubSaturateS(node);
1668 : case IrOpcode::kI8x16Mul:
1669 0 : return MarkAsSimd128(node), VisitI8x16Mul(node);
1670 : case IrOpcode::kI8x16MinS:
1671 7 : return MarkAsSimd128(node), VisitI8x16MinS(node);
1672 : case IrOpcode::kI8x16MaxS:
1673 7 : return MarkAsSimd128(node), VisitI8x16MaxS(node);
1674 : case IrOpcode::kI8x16Eq:
1675 7 : return MarkAsSimd1x16(node), VisitI8x16Eq(node);
1676 : case IrOpcode::kI8x16Ne:
1677 14 : return MarkAsSimd1x16(node), VisitI8x16Ne(node);
1678 : case IrOpcode::kI8x16LtS:
1679 0 : return MarkAsSimd1x16(node), VisitI8x16LtS(node);
1680 : case IrOpcode::kI8x16LeS:
1681 0 : return MarkAsSimd1x16(node), VisitI8x16LeS(node);
1682 : case IrOpcode::kI8x16ShrU:
1683 0 : return MarkAsSimd128(node), VisitI8x16ShrU(node);
1684 : case IrOpcode::kI8x16UConvertI16x8:
1685 0 : return MarkAsSimd128(node), VisitI8x16UConvertI16x8(node);
1686 : case IrOpcode::kI8x16AddSaturateU:
1687 7 : return MarkAsSimd128(node), VisitI8x16AddSaturateU(node);
1688 : case IrOpcode::kI8x16SubSaturateU:
1689 7 : return MarkAsSimd128(node), VisitI8x16SubSaturateU(node);
1690 : case IrOpcode::kI8x16MinU:
1691 7 : return MarkAsSimd128(node), VisitI8x16MinU(node);
1692 : case IrOpcode::kI8x16MaxU:
1693 7 : return MarkAsSimd128(node), VisitI8x16MaxU(node);
1694 : case IrOpcode::kI8x16LtU:
1695 0 : return MarkAsSimd1x16(node), VisitI8x16LtU(node);
1696 : case IrOpcode::kI8x16LeU:
1697 0 : return MarkAsSimd1x16(node), VisitI16x8LeU(node);
1698 : case IrOpcode::kS128Zero:
1699 0 : return MarkAsSimd128(node), VisitS128Zero(node);
1700 : case IrOpcode::kS128And:
1701 0 : return MarkAsSimd128(node), VisitS128And(node);
1702 : case IrOpcode::kS128Or:
1703 0 : return MarkAsSimd128(node), VisitS128Or(node);
1704 : case IrOpcode::kS128Xor:
1705 0 : return MarkAsSimd128(node), VisitS128Xor(node);
1706 : case IrOpcode::kS128Not:
1707 0 : return MarkAsSimd128(node), VisitS128Not(node);
1708 : case IrOpcode::kS32x4ZipLeft:
1709 0 : return MarkAsSimd128(node), VisitS32x4ZipLeft(node);
1710 : case IrOpcode::kS32x4ZipRight:
1711 0 : return MarkAsSimd128(node), VisitS32x4ZipRight(node);
1712 : case IrOpcode::kS32x4UnzipLeft:
1713 0 : return MarkAsSimd128(node), VisitS32x4UnzipLeft(node);
1714 : case IrOpcode::kS32x4UnzipRight:
1715 0 : return MarkAsSimd128(node), VisitS32x4UnzipRight(node);
1716 : case IrOpcode::kS32x4TransposeLeft:
1717 0 : return MarkAsSimd128(node), VisitS32x4TransposeLeft(node);
1718 : case IrOpcode::kS32x4TransposeRight:
1719 0 : return MarkAsSimd128(node), VisitS32x4TransposeRight(node);
1720 : case IrOpcode::kS32x4Select:
1721 21 : return MarkAsSimd128(node), VisitS32x4Select(node);
1722 : case IrOpcode::kS16x8ZipLeft:
1723 0 : return MarkAsSimd128(node), VisitS16x8ZipLeft(node);
1724 : case IrOpcode::kS16x8ZipRight:
1725 0 : return MarkAsSimd128(node), VisitS16x8ZipRight(node);
1726 : case IrOpcode::kS16x8UnzipLeft:
1727 0 : return MarkAsSimd128(node), VisitS16x8UnzipLeft(node);
1728 : case IrOpcode::kS16x8UnzipRight:
1729 0 : return MarkAsSimd128(node), VisitS16x8UnzipRight(node);
1730 : case IrOpcode::kS16x8TransposeLeft:
1731 0 : return MarkAsSimd128(node), VisitS16x8TransposeLeft(node);
1732 : case IrOpcode::kS16x8TransposeRight:
1733 0 : return MarkAsSimd128(node), VisitS16x8TransposeRight(node);
1734 : case IrOpcode::kS16x8Select:
1735 21 : return MarkAsSimd128(node), VisitS16x8Select(node);
1736 : case IrOpcode::kS8x16ZipLeft:
1737 0 : return MarkAsSimd128(node), VisitS8x16ZipLeft(node);
1738 : case IrOpcode::kS8x16ZipRight:
1739 0 : return MarkAsSimd128(node), VisitS8x16ZipRight(node);
1740 : case IrOpcode::kS8x16UnzipLeft:
1741 0 : return MarkAsSimd128(node), VisitS8x16UnzipLeft(node);
1742 : case IrOpcode::kS8x16UnzipRight:
1743 0 : return MarkAsSimd128(node), VisitS8x16UnzipRight(node);
1744 : case IrOpcode::kS8x16TransposeLeft:
1745 0 : return MarkAsSimd128(node), VisitS8x16TransposeLeft(node);
1746 : case IrOpcode::kS8x16TransposeRight:
1747 0 : return MarkAsSimd128(node), VisitS8x16TransposeRight(node);
1748 : case IrOpcode::kS8x16Select:
1749 21 : return MarkAsSimd128(node), VisitS8x16Select(node);
1750 : case IrOpcode::kS8x16Concat:
1751 0 : return MarkAsSimd128(node), VisitS8x16Concat(node);
1752 : case IrOpcode::kS32x2Reverse:
1753 0 : return MarkAsSimd128(node), VisitS32x2Reverse(node);
1754 : case IrOpcode::kS16x4Reverse:
1755 0 : return MarkAsSimd128(node), VisitS16x4Reverse(node);
1756 : case IrOpcode::kS16x2Reverse:
1757 0 : return MarkAsSimd128(node), VisitS16x2Reverse(node);
1758 : case IrOpcode::kS8x8Reverse:
1759 0 : return MarkAsSimd128(node), VisitS8x8Reverse(node);
1760 : case IrOpcode::kS8x4Reverse:
1761 0 : return MarkAsSimd128(node), VisitS8x4Reverse(node);
1762 : case IrOpcode::kS8x2Reverse:
1763 0 : return MarkAsSimd128(node), VisitS8x2Reverse(node);
1764 : case IrOpcode::kS1x4Zero:
1765 0 : return MarkAsSimd1x4(node), VisitS1x4Zero(node);
1766 : case IrOpcode::kS1x4And:
1767 0 : return MarkAsSimd1x4(node), VisitS1x4And(node);
1768 : case IrOpcode::kS1x4Or:
1769 0 : return MarkAsSimd1x4(node), VisitS1x4Or(node);
1770 : case IrOpcode::kS1x4Xor:
1771 0 : return MarkAsSimd1x4(node), VisitS1x4Xor(node);
1772 : case IrOpcode::kS1x4Not:
1773 0 : return MarkAsSimd1x4(node), VisitS1x4Not(node);
1774 : case IrOpcode::kS1x4AnyTrue:
1775 0 : return MarkAsWord32(node), VisitS1x4AnyTrue(node);
1776 : case IrOpcode::kS1x4AllTrue:
1777 0 : return MarkAsWord32(node), VisitS1x4AllTrue(node);
1778 : case IrOpcode::kS1x8Zero:
1779 0 : return MarkAsSimd1x8(node), VisitS1x8Zero(node);
1780 : case IrOpcode::kS1x8And:
1781 0 : return MarkAsSimd1x8(node), VisitS1x8And(node);
1782 : case IrOpcode::kS1x8Or:
1783 0 : return MarkAsSimd1x8(node), VisitS1x8Or(node);
1784 : case IrOpcode::kS1x8Xor:
1785 0 : return MarkAsSimd1x8(node), VisitS1x8Xor(node);
1786 : case IrOpcode::kS1x8Not:
1787 0 : return MarkAsSimd1x8(node), VisitS1x8Not(node);
1788 : case IrOpcode::kS1x8AnyTrue:
1789 0 : return MarkAsWord32(node), VisitS1x8AnyTrue(node);
1790 : case IrOpcode::kS1x8AllTrue:
1791 0 : return MarkAsWord32(node), VisitS1x8AllTrue(node);
1792 : case IrOpcode::kS1x16Zero:
1793 0 : return MarkAsSimd1x16(node), VisitS1x16Zero(node);
1794 : case IrOpcode::kS1x16And:
1795 0 : return MarkAsSimd1x16(node), VisitS1x16And(node);
1796 : case IrOpcode::kS1x16Or:
1797 0 : return MarkAsSimd1x16(node), VisitS1x16Or(node);
1798 : case IrOpcode::kS1x16Xor:
1799 0 : return MarkAsSimd1x16(node), VisitS1x16Xor(node);
1800 : case IrOpcode::kS1x16Not:
1801 0 : return MarkAsSimd1x16(node), VisitS1x16Not(node);
1802 : case IrOpcode::kS1x16AnyTrue:
1803 0 : return MarkAsWord32(node), VisitS1x16AnyTrue(node);
1804 : case IrOpcode::kS1x16AllTrue:
1805 0 : return MarkAsWord32(node), VisitS1x16AllTrue(node);
1806 : default:
1807 : V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d",
1808 0 : node->opcode(), node->op()->mnemonic(), node->id());
1809 : break;
1810 : }
1811 : }
1812 :
1813 43 : void InstructionSelector::VisitLoadStackPointer(Node* node) {
1814 : OperandGenerator g(this);
1815 43 : Emit(kArchStackPointer, g.DefineAsRegister(node));
1816 43 : }
1817 :
1818 4808 : void InstructionSelector::VisitLoadFramePointer(Node* node) {
1819 : OperandGenerator g(this);
1820 4808 : Emit(kArchFramePointer, g.DefineAsRegister(node));
1821 4808 : }
1822 :
1823 53041 : void InstructionSelector::VisitLoadParentFramePointer(Node* node) {
1824 : OperandGenerator g(this);
1825 53041 : Emit(kArchParentFramePointer, g.DefineAsRegister(node));
1826 53041 : }
1827 :
1828 0 : void InstructionSelector::VisitFloat64Acos(Node* node) {
1829 50 : VisitFloat64Ieee754Unop(node, kIeee754Float64Acos);
1830 0 : }
1831 :
1832 0 : void InstructionSelector::VisitFloat64Acosh(Node* node) {
1833 49 : VisitFloat64Ieee754Unop(node, kIeee754Float64Acosh);
1834 0 : }
1835 :
1836 0 : void InstructionSelector::VisitFloat64Asin(Node* node) {
1837 50 : VisitFloat64Ieee754Unop(node, kIeee754Float64Asin);
1838 0 : }
1839 :
1840 0 : void InstructionSelector::VisitFloat64Asinh(Node* node) {
1841 49 : VisitFloat64Ieee754Unop(node, kIeee754Float64Asinh);
1842 0 : }
1843 :
1844 0 : void InstructionSelector::VisitFloat64Atan(Node* node) {
1845 66 : VisitFloat64Ieee754Unop(node, kIeee754Float64Atan);
1846 0 : }
1847 :
1848 0 : void InstructionSelector::VisitFloat64Atanh(Node* node) {
1849 49 : VisitFloat64Ieee754Unop(node, kIeee754Float64Atanh);
1850 0 : }
1851 :
1852 0 : void InstructionSelector::VisitFloat64Atan2(Node* node) {
1853 73 : VisitFloat64Ieee754Binop(node, kIeee754Float64Atan2);
1854 0 : }
1855 :
1856 0 : void InstructionSelector::VisitFloat64Cbrt(Node* node) {
1857 49 : VisitFloat64Ieee754Unop(node, kIeee754Float64Cbrt);
1858 0 : }
1859 :
1860 0 : void InstructionSelector::VisitFloat64Cos(Node* node) {
1861 293 : VisitFloat64Ieee754Unop(node, kIeee754Float64Cos);
1862 0 : }
1863 :
1864 0 : void InstructionSelector::VisitFloat64Cosh(Node* node) {
1865 58 : VisitFloat64Ieee754Unop(node, kIeee754Float64Cosh);
1866 0 : }
1867 :
1868 0 : void InstructionSelector::VisitFloat64Exp(Node* node) {
1869 66 : VisitFloat64Ieee754Unop(node, kIeee754Float64Exp);
1870 0 : }
1871 :
1872 0 : void InstructionSelector::VisitFloat64Expm1(Node* node) {
1873 49 : VisitFloat64Ieee754Unop(node, kIeee754Float64Expm1);
1874 0 : }
1875 :
1876 0 : void InstructionSelector::VisitFloat64Log(Node* node) {
1877 168 : VisitFloat64Ieee754Unop(node, kIeee754Float64Log);
1878 0 : }
1879 :
1880 0 : void InstructionSelector::VisitFloat64Log1p(Node* node) {
1881 49 : VisitFloat64Ieee754Unop(node, kIeee754Float64Log1p);
1882 0 : }
1883 :
1884 0 : void InstructionSelector::VisitFloat64Log2(Node* node) {
1885 49 : VisitFloat64Ieee754Unop(node, kIeee754Float64Log2);
1886 0 : }
1887 :
1888 0 : void InstructionSelector::VisitFloat64Log10(Node* node) {
1889 49 : VisitFloat64Ieee754Unop(node, kIeee754Float64Log10);
1890 0 : }
1891 :
1892 0 : void InstructionSelector::VisitFloat64Pow(Node* node) {
1893 105 : VisitFloat64Ieee754Binop(node, kIeee754Float64Pow);
1894 0 : }
1895 :
1896 0 : void InstructionSelector::VisitFloat64Sin(Node* node) {
1897 293 : VisitFloat64Ieee754Unop(node, kIeee754Float64Sin);
1898 0 : }
1899 :
1900 0 : void InstructionSelector::VisitFloat64Sinh(Node* node) {
1901 58 : VisitFloat64Ieee754Unop(node, kIeee754Float64Sinh);
1902 0 : }
1903 :
1904 0 : void InstructionSelector::VisitFloat64Tan(Node* node) {
1905 66 : VisitFloat64Ieee754Unop(node, kIeee754Float64Tan);
1906 0 : }
1907 :
1908 0 : void InstructionSelector::VisitFloat64Tanh(Node* node) {
1909 58 : VisitFloat64Ieee754Unop(node, kIeee754Float64Tanh);
1910 0 : }
1911 :
1912 6091 : void InstructionSelector::EmitTableSwitch(const SwitchInfo& sw,
1913 6091 : InstructionOperand& index_operand) {
1914 : OperandGenerator g(this);
1915 6091 : size_t input_count = 2 + sw.value_range;
1916 : auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
1917 6091 : inputs[0] = index_operand;
1918 6091 : InstructionOperand default_operand = g.Label(sw.default_branch);
1919 6091 : std::fill(&inputs[1], &inputs[input_count], default_operand);
1920 100666 : for (size_t index = 0; index < sw.case_count; ++index) {
1921 100666 : size_t value = sw.case_values[index] - sw.min_value;
1922 100666 : BasicBlock* branch = sw.case_branches[index];
1923 : DCHECK_LE(0u, value);
1924 : DCHECK_LT(value + 2, input_count);
1925 100666 : inputs[value + 2] = g.Label(branch);
1926 : }
1927 6091 : Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
1928 6091 : }
1929 :
1930 :
1931 17041 : void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw,
1932 17041 : InstructionOperand& value_operand) {
1933 : OperandGenerator g(this);
1934 17041 : size_t input_count = 2 + sw.case_count * 2;
1935 : auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
1936 17041 : inputs[0] = value_operand;
1937 17041 : inputs[1] = g.Label(sw.default_branch);
1938 78564 : for (size_t index = 0; index < sw.case_count; ++index) {
1939 44482 : int32_t value = sw.case_values[index];
1940 44482 : BasicBlock* branch = sw.case_branches[index];
1941 44482 : inputs[index * 2 + 2 + 0] = g.TempImmediate(value);
1942 44482 : inputs[index * 2 + 2 + 1] = g.Label(branch);
1943 : }
1944 17041 : Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
1945 17041 : }
1946 :
1947 2836 : void InstructionSelector::VisitStackSlot(Node* node) {
1948 1418 : int size = StackSlotSizeOf(node->op());
1949 1418 : int slot = frame_->AllocateSpillSlot(size);
1950 : OperandGenerator g(this);
1951 :
1952 : Emit(kArchStackSlot, g.DefineAsRegister(node),
1953 2836 : sequence()->AddImmediate(Constant(slot)), 0, nullptr);
1954 1418 : }
1955 :
1956 0 : void InstructionSelector::VisitBitcastTaggedToWord(Node* node) {
1957 0 : EmitIdentity(node);
1958 0 : }
1959 :
1960 239211 : void InstructionSelector::VisitBitcastWordToTagged(Node* node) {
1961 : OperandGenerator g(this);
1962 239211 : Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(node->InputAt(0)));
1963 239214 : }
1964 :
1965 : // 32 bit targets do not implement the following instructions.
1966 : #if V8_TARGET_ARCH_32_BIT
1967 :
1968 : void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
1969 :
1970 :
1971 : void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); }
1972 :
1973 :
1974 : void InstructionSelector::VisitWord64Xor(Node* node) { UNIMPLEMENTED(); }
1975 :
1976 :
1977 : void InstructionSelector::VisitWord64Shl(Node* node) { UNIMPLEMENTED(); }
1978 :
1979 :
1980 : void InstructionSelector::VisitWord64Shr(Node* node) { UNIMPLEMENTED(); }
1981 :
1982 :
1983 : void InstructionSelector::VisitWord64Sar(Node* node) { UNIMPLEMENTED(); }
1984 :
1985 :
1986 : void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); }
1987 :
1988 :
1989 : void InstructionSelector::VisitWord64Clz(Node* node) { UNIMPLEMENTED(); }
1990 :
1991 :
1992 : void InstructionSelector::VisitWord64Ctz(Node* node) { UNIMPLEMENTED(); }
1993 :
1994 :
1995 : void InstructionSelector::VisitWord64ReverseBits(Node* node) {
1996 : UNIMPLEMENTED();
1997 : }
1998 :
1999 :
2000 : void InstructionSelector::VisitWord64Popcnt(Node* node) { UNIMPLEMENTED(); }
2001 :
2002 :
2003 : void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); }
2004 :
2005 :
2006 : void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
2007 :
2008 :
2009 : void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
2010 : UNIMPLEMENTED();
2011 : }
2012 :
2013 :
2014 : void InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); }
2015 :
2016 :
2017 : void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
2018 : UNIMPLEMENTED();
2019 : }
2020 :
2021 : void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); }
2022 :
2023 :
2024 : void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); }
2025 :
2026 :
2027 : void InstructionSelector::VisitInt64LessThan(Node* node) { UNIMPLEMENTED(); }
2028 :
2029 :
2030 : void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
2031 : UNIMPLEMENTED();
2032 : }
2033 :
2034 :
2035 : void InstructionSelector::VisitUint64Div(Node* node) { UNIMPLEMENTED(); }
2036 :
2037 :
2038 : void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
2039 :
2040 :
2041 : void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); }
2042 :
2043 :
2044 : void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
2045 : UNIMPLEMENTED();
2046 : }
2047 :
2048 :
2049 : void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); }
2050 :
2051 :
2052 : void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
2053 : UNIMPLEMENTED();
2054 : }
2055 :
2056 :
2057 : void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
2058 : UNIMPLEMENTED();
2059 : }
2060 :
2061 : void InstructionSelector::VisitChangeFloat64ToUint64(Node* node) {
2062 : UNIMPLEMENTED();
2063 : }
2064 :
2065 : void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
2066 : UNIMPLEMENTED();
2067 : }
2068 :
2069 :
2070 : void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
2071 : UNIMPLEMENTED();
2072 : }
2073 :
2074 :
2075 : void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
2076 : UNIMPLEMENTED();
2077 : }
2078 :
2079 :
2080 : void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
2081 : UNIMPLEMENTED();
2082 : }
2083 :
2084 :
2085 : void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
2086 : UNIMPLEMENTED();
2087 : }
2088 :
2089 :
2090 : void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
2091 : UNIMPLEMENTED();
2092 : }
2093 :
2094 :
2095 : void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
2096 : UNIMPLEMENTED();
2097 : }
2098 :
2099 :
2100 : void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
2101 : UNIMPLEMENTED();
2102 : }
2103 :
2104 :
2105 : void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
2106 : UNIMPLEMENTED();
2107 : }
2108 :
2109 : void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
2110 : UNIMPLEMENTED();
2111 : }
2112 :
2113 :
2114 : void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
2115 : UNIMPLEMENTED();
2116 : }
2117 : #endif // V8_TARGET_ARCH_32_BIT
2118 :
2119 : // 64 bit targets do not implement the following instructions.
2120 : #if V8_TARGET_ARCH_64_BIT
2121 0 : void InstructionSelector::VisitInt32PairAdd(Node* node) { UNIMPLEMENTED(); }
2122 :
2123 0 : void InstructionSelector::VisitInt32PairSub(Node* node) { UNIMPLEMENTED(); }
2124 :
2125 0 : void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); }
2126 :
2127 0 : void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); }
2128 :
2129 0 : void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); }
2130 :
2131 0 : void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); }
2132 : #endif // V8_TARGET_ARCH_64_BIT
2133 :
2134 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2135 0 : void InstructionSelector::VisitF32x4Splat(Node* node) { UNIMPLEMENTED(); }
2136 :
2137 0 : void InstructionSelector::VisitF32x4ExtractLane(Node* node) { UNIMPLEMENTED(); }
2138 :
2139 0 : void InstructionSelector::VisitF32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2140 :
2141 0 : void InstructionSelector::VisitF32x4SConvertI32x4(Node* node) {
2142 0 : UNIMPLEMENTED();
2143 : }
2144 :
2145 0 : void InstructionSelector::VisitF32x4UConvertI32x4(Node* node) {
2146 0 : UNIMPLEMENTED();
2147 : }
2148 :
2149 0 : void InstructionSelector::VisitF32x4Abs(Node* node) { UNIMPLEMENTED(); }
2150 :
2151 0 : void InstructionSelector::VisitF32x4Neg(Node* node) { UNIMPLEMENTED(); }
2152 :
2153 0 : void InstructionSelector::VisitF32x4RecipSqrtApprox(Node* node) {
2154 0 : UNIMPLEMENTED();
2155 : }
2156 :
2157 0 : void InstructionSelector::VisitF32x4Add(Node* node) { UNIMPLEMENTED(); }
2158 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2159 :
2160 : #if !V8_TARGET_ARCH_ARM
2161 0 : void InstructionSelector::VisitF32x4AddHoriz(Node* node) { UNIMPLEMENTED(); }
2162 : #endif // !V8_TARGET_ARCH_ARM
2163 :
2164 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2165 0 : void InstructionSelector::VisitF32x4Sub(Node* node) { UNIMPLEMENTED(); }
2166 :
2167 0 : void InstructionSelector::VisitF32x4Mul(Node* node) { UNIMPLEMENTED(); }
2168 :
2169 0 : void InstructionSelector::VisitF32x4Max(Node* node) { UNIMPLEMENTED(); }
2170 :
2171 0 : void InstructionSelector::VisitF32x4Min(Node* node) { UNIMPLEMENTED(); }
2172 :
2173 0 : void InstructionSelector::VisitF32x4RecipApprox(Node* node) { UNIMPLEMENTED(); }
2174 :
2175 0 : void InstructionSelector::VisitF32x4Eq(Node* node) { UNIMPLEMENTED(); }
2176 :
2177 0 : void InstructionSelector::VisitF32x4Ne(Node* node) { UNIMPLEMENTED(); }
2178 :
2179 0 : void InstructionSelector::VisitF32x4Lt(Node* node) { UNIMPLEMENTED(); }
2180 :
2181 0 : void InstructionSelector::VisitF32x4Le(Node* node) { UNIMPLEMENTED(); }
2182 : #endif // V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2183 :
2184 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_IA32 && \
2185 : !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2186 : void InstructionSelector::VisitI32x4Splat(Node* node) { UNIMPLEMENTED(); }
2187 :
2188 : void InstructionSelector::VisitI32x4ExtractLane(Node* node) { UNIMPLEMENTED(); }
2189 :
2190 : void InstructionSelector::VisitI32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2191 :
2192 : void InstructionSelector::VisitI32x4Add(Node* node) { UNIMPLEMENTED(); }
2193 :
2194 : void InstructionSelector::VisitI32x4Sub(Node* node) { UNIMPLEMENTED(); }
2195 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_IA32 &&
2196 : // !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2197 :
2198 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && \
2199 : !V8_TARGET_ARCH_MIPS64
2200 : void InstructionSelector::VisitI32x4Shl(Node* node) { UNIMPLEMENTED(); }
2201 :
2202 : void InstructionSelector::VisitI32x4ShrS(Node* node) { UNIMPLEMENTED(); }
2203 :
2204 : void InstructionSelector::VisitI32x4Mul(Node* node) { UNIMPLEMENTED(); }
2205 :
2206 : void InstructionSelector::VisitI32x4MaxS(Node* node) { UNIMPLEMENTED(); }
2207 :
2208 : void InstructionSelector::VisitI32x4MinS(Node* node) { UNIMPLEMENTED(); }
2209 :
2210 : void InstructionSelector::VisitI32x4Eq(Node* node) { UNIMPLEMENTED(); }
2211 :
2212 : void InstructionSelector::VisitI32x4Ne(Node* node) { UNIMPLEMENTED(); }
2213 :
2214 : void InstructionSelector::VisitI32x4MinU(Node* node) { UNIMPLEMENTED(); }
2215 :
2216 : void InstructionSelector::VisitI32x4MaxU(Node* node) { UNIMPLEMENTED(); }
2217 :
2218 : void InstructionSelector::VisitI32x4ShrU(Node* node) { UNIMPLEMENTED(); }
2219 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS &&
2220 : // !V8_TARGET_ARCH_MIPS64
2221 :
2222 : #if !V8_TARGET_ARCH_ARM
2223 0 : void InstructionSelector::VisitI32x4AddHoriz(Node* node) { UNIMPLEMENTED(); }
2224 : #endif // !V8_TARGET_ARCH_ARM
2225 :
2226 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2227 0 : void InstructionSelector::VisitI32x4SConvertF32x4(Node* node) {
2228 0 : UNIMPLEMENTED();
2229 : }
2230 :
2231 0 : void InstructionSelector::VisitI32x4UConvertF32x4(Node* node) {
2232 0 : UNIMPLEMENTED();
2233 : }
2234 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2235 :
2236 : #if !V8_TARGET_ARCH_ARM
2237 0 : void InstructionSelector::VisitI32x4SConvertI16x8Low(Node* node) {
2238 0 : UNIMPLEMENTED();
2239 : }
2240 :
2241 0 : void InstructionSelector::VisitI32x4SConvertI16x8High(Node* node) {
2242 0 : UNIMPLEMENTED();
2243 : }
2244 :
2245 0 : void InstructionSelector::VisitI32x4Neg(Node* node) { UNIMPLEMENTED(); }
2246 :
2247 0 : void InstructionSelector::VisitI32x4LtS(Node* node) { UNIMPLEMENTED(); }
2248 :
2249 0 : void InstructionSelector::VisitI32x4LeS(Node* node) { UNIMPLEMENTED(); }
2250 :
2251 0 : void InstructionSelector::VisitI32x4UConvertI16x8Low(Node* node) {
2252 0 : UNIMPLEMENTED();
2253 : }
2254 :
2255 0 : void InstructionSelector::VisitI32x4UConvertI16x8High(Node* node) {
2256 0 : UNIMPLEMENTED();
2257 : }
2258 :
2259 0 : void InstructionSelector::VisitI32x4LtU(Node* node) { UNIMPLEMENTED(); }
2260 :
2261 0 : void InstructionSelector::VisitI32x4LeU(Node* node) { UNIMPLEMENTED(); }
2262 : #endif // !V8_TARGET_ARCH_ARM
2263 :
2264 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2265 : void InstructionSelector::VisitI16x8Splat(Node* node) { UNIMPLEMENTED(); }
2266 :
2267 : void InstructionSelector::VisitI16x8ExtractLane(Node* node) { UNIMPLEMENTED(); }
2268 :
2269 : void InstructionSelector::VisitI16x8ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2270 :
2271 : void InstructionSelector::VisitI16x8Shl(Node* node) { UNIMPLEMENTED(); }
2272 :
2273 : void InstructionSelector::VisitI16x8ShrS(Node* node) { UNIMPLEMENTED(); }
2274 :
2275 : void InstructionSelector::VisitI16x8Add(Node* node) { UNIMPLEMENTED(); }
2276 :
2277 : void InstructionSelector::VisitI16x8AddSaturateS(Node* node) {
2278 : UNIMPLEMENTED();
2279 : }
2280 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2281 :
2282 : #if !V8_TARGET_ARCH_ARM
2283 0 : void InstructionSelector::VisitI16x8AddHoriz(Node* node) { UNIMPLEMENTED(); }
2284 : #endif // !V8_TARGET_ARCH_ARM
2285 :
2286 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2287 : void InstructionSelector::VisitI16x8Sub(Node* node) { UNIMPLEMENTED(); }
2288 :
2289 : void InstructionSelector::VisitI16x8SubSaturateS(Node* node) {
2290 : UNIMPLEMENTED();
2291 : }
2292 :
2293 : void InstructionSelector::VisitI16x8Mul(Node* node) { UNIMPLEMENTED(); }
2294 :
2295 : void InstructionSelector::VisitI16x8MinS(Node* node) { UNIMPLEMENTED(); }
2296 :
2297 : void InstructionSelector::VisitI16x8MaxS(Node* node) { UNIMPLEMENTED(); }
2298 :
2299 : void InstructionSelector::VisitI16x8Eq(Node* node) { UNIMPLEMENTED(); }
2300 :
2301 : void InstructionSelector::VisitI16x8Ne(Node* node) { UNIMPLEMENTED(); }
2302 :
2303 : void InstructionSelector::VisitI16x8ShrU(Node* node) { UNIMPLEMENTED(); }
2304 :
2305 : void InstructionSelector::VisitI16x8AddSaturateU(Node* node) {
2306 : UNIMPLEMENTED();
2307 : }
2308 :
2309 : void InstructionSelector::VisitI16x8SubSaturateU(Node* node) {
2310 : UNIMPLEMENTED();
2311 : }
2312 :
2313 : void InstructionSelector::VisitI16x8MinU(Node* node) { UNIMPLEMENTED(); }
2314 :
2315 : void InstructionSelector::VisitI16x8MaxU(Node* node) { UNIMPLEMENTED(); }
2316 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2317 :
2318 : #if !V8_TARGET_ARCH_ARM
2319 0 : void InstructionSelector::VisitI16x8Neg(Node* node) { UNIMPLEMENTED(); }
2320 :
2321 0 : void InstructionSelector::VisitI16x8SConvertI32x4(Node* node) {
2322 0 : UNIMPLEMENTED();
2323 : }
2324 :
2325 0 : void InstructionSelector::VisitI16x8SConvertI8x16Low(Node* node) {
2326 0 : UNIMPLEMENTED();
2327 : }
2328 :
2329 0 : void InstructionSelector::VisitI16x8UConvertI8x16Low(Node* node) {
2330 0 : UNIMPLEMENTED();
2331 : }
2332 :
2333 0 : void InstructionSelector::VisitI16x8UConvertI8x16High(Node* node) {
2334 0 : UNIMPLEMENTED();
2335 : }
2336 :
2337 0 : void InstructionSelector::VisitI16x8SConvertI8x16High(Node* node) {
2338 0 : UNIMPLEMENTED();
2339 : }
2340 :
2341 0 : void InstructionSelector::VisitI16x8LtS(Node* node) { UNIMPLEMENTED(); }
2342 :
2343 0 : void InstructionSelector::VisitI16x8LeS(Node* node) { UNIMPLEMENTED(); }
2344 :
2345 0 : void InstructionSelector::VisitI16x8UConvertI32x4(Node* node) {
2346 0 : UNIMPLEMENTED();
2347 : }
2348 :
2349 0 : void InstructionSelector::VisitI16x8LtU(Node* node) { UNIMPLEMENTED(); }
2350 :
2351 0 : void InstructionSelector::VisitI16x8LeU(Node* node) { UNIMPLEMENTED(); }
2352 : #endif // !V8_TARGET_ARCH_ARM
2353 :
2354 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2355 : void InstructionSelector::VisitI8x16Splat(Node* node) { UNIMPLEMENTED(); }
2356 :
2357 : void InstructionSelector::VisitI8x16ExtractLane(Node* node) { UNIMPLEMENTED(); }
2358 :
2359 : void InstructionSelector::VisitI8x16ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2360 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2361 :
2362 : #if !V8_TARGET_ARCH_ARM
2363 0 : void InstructionSelector::VisitI8x16Neg(Node* node) { UNIMPLEMENTED(); }
2364 :
2365 0 : void InstructionSelector::VisitI8x16Shl(Node* node) { UNIMPLEMENTED(); }
2366 :
2367 0 : void InstructionSelector::VisitI8x16ShrS(Node* node) { UNIMPLEMENTED(); }
2368 :
2369 0 : void InstructionSelector::VisitI8x16SConvertI16x8(Node* node) {
2370 0 : UNIMPLEMENTED();
2371 : }
2372 : #endif // !V8_TARGET_ARCH_ARM
2373 :
2374 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2375 : void InstructionSelector::VisitI8x16Add(Node* node) { UNIMPLEMENTED(); }
2376 :
2377 : void InstructionSelector::VisitI8x16AddSaturateS(Node* node) {
2378 : UNIMPLEMENTED();
2379 : }
2380 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2381 :
2382 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2383 : void InstructionSelector::VisitI8x16Sub(Node* node) { UNIMPLEMENTED(); }
2384 :
2385 : void InstructionSelector::VisitI8x16SubSaturateS(Node* node) {
2386 : UNIMPLEMENTED();
2387 : }
2388 :
2389 : void InstructionSelector::VisitI8x16MinS(Node* node) { UNIMPLEMENTED(); }
2390 :
2391 : void InstructionSelector::VisitI8x16MaxS(Node* node) { UNIMPLEMENTED(); }
2392 :
2393 : void InstructionSelector::VisitI8x16Eq(Node* node) { UNIMPLEMENTED(); }
2394 :
2395 : void InstructionSelector::VisitI8x16Ne(Node* node) { UNIMPLEMENTED(); }
2396 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2397 :
2398 : #if !V8_TARGET_ARCH_ARM
2399 0 : void InstructionSelector::VisitI8x16Mul(Node* node) { UNIMPLEMENTED(); }
2400 :
2401 0 : void InstructionSelector::VisitI8x16LtS(Node* node) { UNIMPLEMENTED(); }
2402 :
2403 0 : void InstructionSelector::VisitI8x16LeS(Node* node) { UNIMPLEMENTED(); }
2404 :
2405 0 : void InstructionSelector::VisitI8x16ShrU(Node* node) { UNIMPLEMENTED(); }
2406 :
2407 0 : void InstructionSelector::VisitI8x16UConvertI16x8(Node* node) {
2408 0 : UNIMPLEMENTED();
2409 : }
2410 : #endif // !V8_TARGET_ARCH_ARM
2411 :
2412 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2413 : void InstructionSelector::VisitI8x16AddSaturateU(Node* node) {
2414 : UNIMPLEMENTED();
2415 : }
2416 :
2417 : void InstructionSelector::VisitI8x16SubSaturateU(Node* node) {
2418 : UNIMPLEMENTED();
2419 : }
2420 :
2421 : void InstructionSelector::VisitI8x16MinU(Node* node) { UNIMPLEMENTED(); }
2422 :
2423 : void InstructionSelector::VisitI8x16MaxU(Node* node) { UNIMPLEMENTED(); }
2424 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2425 :
2426 : #if !V8_TARGET_ARCH_ARM
2427 0 : void InstructionSelector::VisitI8x16LtU(Node* node) { UNIMPLEMENTED(); }
2428 :
2429 0 : void InstructionSelector::VisitI8x16LeU(Node* node) { UNIMPLEMENTED(); }
2430 :
2431 0 : void InstructionSelector::VisitS128And(Node* node) { UNIMPLEMENTED(); }
2432 :
2433 0 : void InstructionSelector::VisitS128Or(Node* node) { UNIMPLEMENTED(); }
2434 :
2435 0 : void InstructionSelector::VisitS128Xor(Node* node) { UNIMPLEMENTED(); }
2436 :
2437 0 : void InstructionSelector::VisitS128Not(Node* node) { UNIMPLEMENTED(); }
2438 : #endif // !V8_TARGET_ARCH_ARM
2439 :
2440 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && \
2441 : !V8_TARGET_ARCH_MIPS64
2442 : void InstructionSelector::VisitS128Zero(Node* node) { UNIMPLEMENTED(); }
2443 :
2444 : void InstructionSelector::VisitS1x4Zero(Node* node) { UNIMPLEMENTED(); }
2445 :
2446 : void InstructionSelector::VisitS1x8Zero(Node* node) { UNIMPLEMENTED(); }
2447 :
2448 : void InstructionSelector::VisitS1x16Zero(Node* node) { UNIMPLEMENTED(); }
2449 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS &&
2450 : // !V8_TARGET_ARCH_MIPS64
2451 :
2452 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && \
2453 : !V8_TARGET_ARCH_MIPS64
2454 : void InstructionSelector::VisitS32x4Select(Node* node) { UNIMPLEMENTED(); }
2455 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS &&
2456 : // !V8_TARGET_ARCH_MIPS64
2457 :
2458 : #if !V8_TARGET_ARCH_ARM
2459 0 : void InstructionSelector::VisitS32x4ZipLeft(Node* node) { UNIMPLEMENTED(); }
2460 :
2461 0 : void InstructionSelector::VisitS32x4ZipRight(Node* node) { UNIMPLEMENTED(); }
2462 :
2463 0 : void InstructionSelector::VisitS32x4UnzipLeft(Node* node) { UNIMPLEMENTED(); }
2464 :
2465 0 : void InstructionSelector::VisitS32x4UnzipRight(Node* node) { UNIMPLEMENTED(); }
2466 :
2467 0 : void InstructionSelector::VisitS32x4TransposeLeft(Node* node) {
2468 0 : UNIMPLEMENTED();
2469 : }
2470 :
2471 0 : void InstructionSelector::VisitS32x4TransposeRight(Node* node) {
2472 0 : UNIMPLEMENTED();
2473 : }
2474 :
2475 0 : void InstructionSelector::VisitS16x8ZipLeft(Node* node) { UNIMPLEMENTED(); }
2476 :
2477 0 : void InstructionSelector::VisitS16x8ZipRight(Node* node) { UNIMPLEMENTED(); }
2478 :
2479 0 : void InstructionSelector::VisitS16x8UnzipLeft(Node* node) { UNIMPLEMENTED(); }
2480 :
2481 0 : void InstructionSelector::VisitS16x8UnzipRight(Node* node) { UNIMPLEMENTED(); }
2482 :
2483 0 : void InstructionSelector::VisitS16x8TransposeLeft(Node* node) {
2484 0 : UNIMPLEMENTED();
2485 : }
2486 :
2487 0 : void InstructionSelector::VisitS16x8TransposeRight(Node* node) {
2488 0 : UNIMPLEMENTED();
2489 : }
2490 : #endif // !V8_TARGET_ARCH_ARM
2491 :
2492 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2493 : void InstructionSelector::VisitS16x8Select(Node* node) { UNIMPLEMENTED(); }
2494 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2495 :
2496 : #if !V8_TARGET_ARCH_ARM
2497 0 : void InstructionSelector::VisitS8x16ZipLeft(Node* node) { UNIMPLEMENTED(); }
2498 :
2499 0 : void InstructionSelector::VisitS8x16ZipRight(Node* node) { UNIMPLEMENTED(); }
2500 :
2501 0 : void InstructionSelector::VisitS8x16UnzipLeft(Node* node) { UNIMPLEMENTED(); }
2502 :
2503 0 : void InstructionSelector::VisitS8x16UnzipRight(Node* node) { UNIMPLEMENTED(); }
2504 :
2505 0 : void InstructionSelector::VisitS8x16TransposeLeft(Node* node) {
2506 0 : UNIMPLEMENTED();
2507 : }
2508 :
2509 0 : void InstructionSelector::VisitS8x16TransposeRight(Node* node) {
2510 0 : UNIMPLEMENTED();
2511 : }
2512 : #endif // !V8_TARGET_ARCH_ARM
2513 :
2514 : #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2515 : void InstructionSelector::VisitS8x16Select(Node* node) { UNIMPLEMENTED(); }
2516 : #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
2517 :
2518 : #if !V8_TARGET_ARCH_ARM
2519 0 : void InstructionSelector::VisitS8x16Concat(Node* node) { UNIMPLEMENTED(); }
2520 :
2521 0 : void InstructionSelector::VisitS32x2Reverse(Node* node) { UNIMPLEMENTED(); }
2522 :
2523 0 : void InstructionSelector::VisitS16x4Reverse(Node* node) { UNIMPLEMENTED(); }
2524 :
2525 0 : void InstructionSelector::VisitS16x2Reverse(Node* node) { UNIMPLEMENTED(); }
2526 :
2527 0 : void InstructionSelector::VisitS8x8Reverse(Node* node) { UNIMPLEMENTED(); }
2528 :
2529 0 : void InstructionSelector::VisitS8x4Reverse(Node* node) { UNIMPLEMENTED(); }
2530 :
2531 0 : void InstructionSelector::VisitS8x2Reverse(Node* node) { UNIMPLEMENTED(); }
2532 :
2533 0 : void InstructionSelector::VisitS1x4And(Node* node) { UNIMPLEMENTED(); }
2534 :
2535 0 : void InstructionSelector::VisitS1x4Or(Node* node) { UNIMPLEMENTED(); }
2536 :
2537 0 : void InstructionSelector::VisitS1x4Xor(Node* node) { UNIMPLEMENTED(); }
2538 :
2539 0 : void InstructionSelector::VisitS1x4Not(Node* node) { UNIMPLEMENTED(); }
2540 :
2541 0 : void InstructionSelector::VisitS1x4AnyTrue(Node* node) { UNIMPLEMENTED(); }
2542 :
2543 0 : void InstructionSelector::VisitS1x4AllTrue(Node* node) { UNIMPLEMENTED(); }
2544 :
2545 0 : void InstructionSelector::VisitS1x8And(Node* node) { UNIMPLEMENTED(); }
2546 :
2547 0 : void InstructionSelector::VisitS1x8Or(Node* node) { UNIMPLEMENTED(); }
2548 :
2549 0 : void InstructionSelector::VisitS1x8Xor(Node* node) { UNIMPLEMENTED(); }
2550 :
2551 0 : void InstructionSelector::VisitS1x8Not(Node* node) { UNIMPLEMENTED(); }
2552 :
2553 0 : void InstructionSelector::VisitS1x8AnyTrue(Node* node) { UNIMPLEMENTED(); }
2554 :
2555 0 : void InstructionSelector::VisitS1x8AllTrue(Node* node) { UNIMPLEMENTED(); }
2556 :
2557 0 : void InstructionSelector::VisitS1x16And(Node* node) { UNIMPLEMENTED(); }
2558 :
2559 0 : void InstructionSelector::VisitS1x16Or(Node* node) { UNIMPLEMENTED(); }
2560 :
2561 0 : void InstructionSelector::VisitS1x16Xor(Node* node) { UNIMPLEMENTED(); }
2562 :
2563 0 : void InstructionSelector::VisitS1x16Not(Node* node) { UNIMPLEMENTED(); }
2564 :
2565 0 : void InstructionSelector::VisitS1x16AnyTrue(Node* node) { UNIMPLEMENTED(); }
2566 :
2567 0 : void InstructionSelector::VisitS1x16AllTrue(Node* node) { UNIMPLEMENTED(); }
2568 : #endif // !V8_TARGET_ARCH_ARM
2569 :
2570 12945 : void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); }
2571 :
2572 7602740 : void InstructionSelector::VisitParameter(Node* node) {
2573 : OperandGenerator g(this);
2574 1791072 : int index = ParameterIndexOf(node->op());
2575 : InstructionOperand op =
2576 1791088 : linkage()->ParameterHasSecondaryLocation(index)
2577 : ? g.DefineAsDualLocation(
2578 : node, linkage()->GetParameterLocation(index),
2579 876924 : linkage()->GetParameterSecondaryLocation(index))
2580 3582133 : : g.DefineAsLocation(node, linkage()->GetParameterLocation(index));
2581 :
2582 1791089 : Emit(kArchNop, op);
2583 1791094 : }
2584 :
2585 : namespace {
2586 : LinkageLocation ExceptionLocation() {
2587 : return LinkageLocation::ForRegister(kReturnRegister0.code(),
2588 : MachineType::IntPtr());
2589 : }
2590 : }
2591 :
2592 209287 : void InstructionSelector::VisitIfException(Node* node) {
2593 : OperandGenerator g(this);
2594 : DCHECK_EQ(IrOpcode::kCall, node->InputAt(1)->opcode());
2595 209287 : Emit(kArchNop, g.DefineAsLocation(node, ExceptionLocation()));
2596 209288 : }
2597 :
2598 :
2599 77685 : void InstructionSelector::VisitOsrValue(Node* node) {
2600 : OperandGenerator g(this);
2601 25895 : int index = OsrValueIndexOf(node->op());
2602 : Emit(kArchNop,
2603 25895 : g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index)));
2604 25895 : }
2605 :
2606 :
2607 2667132 : void InstructionSelector::VisitPhi(Node* node) {
2608 1333564 : const int input_count = node->op()->ValueInputCount();
2609 : PhiInstruction* phi = new (instruction_zone())
2610 : PhiInstruction(instruction_zone(), GetVirtualRegister(node),
2611 2667134 : static_cast<size_t>(input_count));
2612 : sequence()
2613 : ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number()))
2614 2667136 : ->AddPhi(phi);
2615 4659090 : for (int i = 0; i < input_count; ++i) {
2616 : Node* const input = node->InputAt(i);
2617 : MarkAsUsed(input);
2618 3325519 : phi->SetInput(static_cast<size_t>(i), GetVirtualRegister(input));
2619 : }
2620 1333571 : }
2621 :
2622 :
2623 654995 : void InstructionSelector::VisitProjection(Node* node) {
2624 : OperandGenerator g(this);
2625 330922 : Node* value = node->InputAt(0);
2626 330922 : switch (value->opcode()) {
2627 : case IrOpcode::kInt32AddWithOverflow:
2628 : case IrOpcode::kInt32SubWithOverflow:
2629 : case IrOpcode::kInt32MulWithOverflow:
2630 : case IrOpcode::kInt64AddWithOverflow:
2631 : case IrOpcode::kInt64SubWithOverflow:
2632 : case IrOpcode::kTryTruncateFloat32ToInt64:
2633 : case IrOpcode::kTryTruncateFloat64ToInt64:
2634 : case IrOpcode::kTryTruncateFloat32ToUint64:
2635 : case IrOpcode::kTryTruncateFloat64ToUint64:
2636 : case IrOpcode::kInt32PairAdd:
2637 : case IrOpcode::kInt32PairSub:
2638 : case IrOpcode::kInt32PairMul:
2639 : case IrOpcode::kWord32PairShl:
2640 : case IrOpcode::kWord32PairShr:
2641 : case IrOpcode::kWord32PairSar:
2642 : case IrOpcode::kInt32AbsWithOverflow:
2643 : case IrOpcode::kInt64AbsWithOverflow:
2644 324073 : if (ProjectionIndexOf(node->op()) == 0u) {
2645 196511 : Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
2646 : } else {
2647 : DCHECK(ProjectionIndexOf(node->op()) == 1u);
2648 : MarkAsUsed(value);
2649 : }
2650 : break;
2651 : default:
2652 : break;
2653 : }
2654 330922 : }
2655 :
2656 :
2657 9047133 : void InstructionSelector::VisitConstant(Node* node) {
2658 : // We must emit a NOP here because every live range needs a defining
2659 : // instruction in the register allocator.
2660 : OperandGenerator g(this);
2661 9047133 : Emit(kArchNop, g.DefineAsConstant(node));
2662 9047155 : }
2663 :
2664 :
2665 17004579 : void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
2666 : OperandGenerator g(this);
2667 9217304 : const CallDescriptor* descriptor = CallDescriptorOf(node->op());
2668 :
2669 : FrameStateDescriptor* frame_state_descriptor = nullptr;
2670 3400922 : if (descriptor->NeedsFrameState()) {
2671 : frame_state_descriptor = GetFrameStateDescriptor(
2672 4826862 : node->InputAt(static_cast<int>(descriptor->InputCount())));
2673 : }
2674 :
2675 3400920 : CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
2676 :
2677 : // Compute InstructionOperands for inputs and outputs.
2678 : // TODO(turbofan): on some architectures it's probably better to use
2679 : // the code object in a register if there are multiple uses of it.
2680 : // Improve constant pool and the heuristics in the register allocator
2681 : // for where to emit constants.
2682 : CallBufferFlags call_buffer_flags(kCallCodeImmediate | kCallAddressImmediate);
2683 3400939 : InitializeCallBuffer(node, &buffer, call_buffer_flags);
2684 :
2685 3400926 : EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node);
2686 :
2687 : // Pass label of exception handler block.
2688 : CallDescriptor::Flags flags = descriptor->flags();
2689 3400869 : if (handler) {
2690 : DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode());
2691 : flags |= CallDescriptor::kHasExceptionHandler;
2692 462780 : buffer.instruction_args.push_back(g.Label(handler));
2693 : }
2694 :
2695 : bool from_native_stack = linkage()->GetIncomingDescriptor()->UseNativeStack();
2696 : bool to_native_stack = descriptor->UseNativeStack();
2697 3400869 : if (from_native_stack != to_native_stack) {
2698 : // (arm64 only) Mismatch in the use of stack pointers. One or the other
2699 : // has to be restored manually by the code generator.
2700 177672 : flags |= to_native_stack ? CallDescriptor::kRestoreJSSP
2701 : : CallDescriptor::kRestoreCSP;
2702 : }
2703 :
2704 : // Select the appropriate opcode based on the call type.
2705 : InstructionCode opcode = kArchNop;
2706 3400869 : switch (descriptor->kind()) {
2707 : case CallDescriptor::kCallAddress:
2708 : opcode =
2709 2084 : kArchCallCFunction |
2710 2084 : MiscField::encode(static_cast<int>(descriptor->ParameterCount()));
2711 2084 : break;
2712 : case CallDescriptor::kCallCodeObject:
2713 3247062 : opcode = kArchCallCodeObject | MiscField::encode(flags);
2714 3247062 : break;
2715 : case CallDescriptor::kCallJSFunction:
2716 151767 : opcode = kArchCallJSFunction | MiscField::encode(flags);
2717 151767 : break;
2718 : }
2719 :
2720 : // Emit the call instruction.
2721 3400869 : size_t const output_count = buffer.outputs.size();
2722 3400869 : auto* outputs = output_count ? &buffer.outputs.front() : nullptr;
2723 : Instruction* call_instr =
2724 : Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
2725 6801738 : &buffer.instruction_args.front());
2726 6801900 : if (instruction_selection_failed()) return;
2727 : call_instr->MarkAsCall();
2728 : }
2729 :
2730 :
2731 1044582 : void InstructionSelector::VisitTailCall(Node* node) {
2732 : OperandGenerator g(this);
2733 298452 : CallDescriptor const* descriptor = CallDescriptorOf(node->op());
2734 : DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls);
2735 :
2736 : CallDescriptor* caller = linkage()->GetIncomingDescriptor();
2737 : DCHECK(caller->CanTailCall(node));
2738 149226 : const CallDescriptor* callee = CallDescriptorOf(node->op());
2739 149226 : int stack_param_delta = callee->GetStackParameterDelta(caller);
2740 149226 : CallBuffer buffer(zone(), descriptor, nullptr);
2741 :
2742 : // Compute InstructionOperands for inputs and outputs.
2743 : CallBufferFlags flags(kCallCodeImmediate | kCallTail);
2744 149226 : if (IsTailCallAddressImmediate()) {
2745 : flags |= kCallAddressImmediate;
2746 : }
2747 149226 : InitializeCallBuffer(node, &buffer, flags, stack_param_delta);
2748 :
2749 : // Select the appropriate opcode based on the call type.
2750 : InstructionCode opcode;
2751 : InstructionOperandVector temps(zone());
2752 149226 : if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
2753 1041 : switch (descriptor->kind()) {
2754 : case CallDescriptor::kCallCodeObject:
2755 : opcode = kArchTailCallCodeObjectFromJSFunction;
2756 : break;
2757 : case CallDescriptor::kCallJSFunction:
2758 : opcode = kArchTailCallJSFunctionFromJSFunction;
2759 177 : break;
2760 : default:
2761 0 : UNREACHABLE();
2762 : return;
2763 : }
2764 1041 : int temps_count = GetTempsCountForTailCallFromJSFunction();
2765 4164 : for (int i = 0; i < temps_count; i++) {
2766 6246 : temps.push_back(g.TempRegister());
2767 : }
2768 : } else {
2769 148185 : switch (descriptor->kind()) {
2770 : case CallDescriptor::kCallCodeObject:
2771 : opcode = kArchTailCallCodeObject;
2772 : break;
2773 : case CallDescriptor::kCallAddress:
2774 : opcode = kArchTailCallAddress;
2775 23736 : break;
2776 : default:
2777 0 : UNREACHABLE();
2778 : return;
2779 : }
2780 : }
2781 149226 : opcode |= MiscField::encode(descriptor->flags());
2782 :
2783 149226 : Emit(kArchPrepareTailCall, g.NoOutput());
2784 :
2785 : int first_unused_stack_slot =
2786 : (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0) +
2787 149226 : stack_param_delta;
2788 298452 : buffer.instruction_args.push_back(g.TempImmediate(first_unused_stack_slot));
2789 :
2790 : // Emit the tailcall instruction.
2791 : Emit(opcode, 0, nullptr, buffer.instruction_args.size(),
2792 : &buffer.instruction_args.front(), temps.size(),
2793 447678 : temps.empty() ? nullptr : &temps.front());
2794 149226 : }
2795 :
2796 :
2797 5916205 : void InstructionSelector::VisitGoto(BasicBlock* target) {
2798 : // jump to the next block.
2799 : OperandGenerator g(this);
2800 5916205 : Emit(kArchJmp, g.NoOutput(), g.Label(target));
2801 5916252 : }
2802 :
2803 5439605 : void InstructionSelector::VisitReturn(Node* ret) {
2804 : OperandGenerator g(this);
2805 1093932 : const int input_count = linkage()->GetIncomingDescriptor()->ReturnCount() == 0
2806 : ? 1
2807 2172469 : : ret->op()->ValueInputCount();
2808 : DCHECK_GE(input_count, 1);
2809 1093932 : auto value_locations = zone()->NewArray<InstructionOperand>(input_count);
2810 1093925 : Node* pop_count = ret->InputAt(0);
2811 910 : value_locations[0] = (pop_count->opcode() == IrOpcode::kInt32Constant ||
2812 : pop_count->opcode() == IrOpcode::kInt64Constant)
2813 : ? g.UseImmediate(pop_count)
2814 2186940 : : g.UseRegister(pop_count);
2815 1079302 : for (int i = 1; i < input_count; ++i) {
2816 : value_locations[i] =
2817 2158544 : g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i - 1));
2818 : }
2819 1093940 : Emit(kArchRet, 0, nullptr, input_count, value_locations);
2820 1093950 : }
2821 :
2822 0 : Instruction* InstructionSelector::EmitDeoptimize(
2823 : InstructionCode opcode, InstructionOperand output, InstructionOperand a,
2824 : DeoptimizeKind kind, DeoptimizeReason reason, Node* frame_state) {
2825 0 : size_t output_count = output.IsInvalid() ? 0 : 1;
2826 0 : InstructionOperand inputs[] = {a};
2827 : size_t input_count = arraysize(inputs);
2828 : return EmitDeoptimize(opcode, output_count, &output, input_count, inputs,
2829 0 : kind, reason, frame_state);
2830 : }
2831 :
2832 127898 : Instruction* InstructionSelector::EmitDeoptimize(
2833 : InstructionCode opcode, InstructionOperand output, InstructionOperand a,
2834 : InstructionOperand b, DeoptimizeKind kind, DeoptimizeReason reason,
2835 : Node* frame_state) {
2836 127898 : size_t output_count = output.IsInvalid() ? 0 : 1;
2837 127898 : InstructionOperand inputs[] = {a, b};
2838 : size_t input_count = arraysize(inputs);
2839 : return EmitDeoptimize(opcode, output_count, &output, input_count, inputs,
2840 127898 : kind, reason, frame_state);
2841 : }
2842 :
2843 282952 : Instruction* InstructionSelector::EmitDeoptimize(
2844 : InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
2845 : size_t input_count, InstructionOperand* inputs, DeoptimizeKind kind,
2846 282960 : DeoptimizeReason reason, Node* frame_state) {
2847 : OperandGenerator g(this);
2848 282952 : FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state);
2849 : InstructionOperandVector args(instruction_zone());
2850 282953 : args.reserve(input_count + 1 + descriptor->GetTotalSize());
2851 888259 : for (size_t i = 0; i < input_count; ++i) {
2852 605299 : args.push_back(inputs[i]);
2853 : }
2854 282960 : opcode |= MiscField::encode(static_cast<int>(input_count));
2855 : int const state_id =
2856 282960 : sequence()->AddDeoptimizationEntry(descriptor, kind, reason);
2857 565911 : args.push_back(g.TempImmediate(state_id));
2858 : StateObjectDeduplicator deduplicator(instruction_zone());
2859 : AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator,
2860 : &args, FrameStateInputKind::kAny,
2861 282955 : instruction_zone());
2862 : return Emit(opcode, output_count, outputs, args.size(), &args.front(), 0,
2863 565922 : nullptr);
2864 : }
2865 :
2866 110406 : void InstructionSelector::EmitIdentity(Node* node) {
2867 : OperandGenerator g(this);
2868 : MarkAsUsed(node->InputAt(0));
2869 110406 : SetRename(node, node->InputAt(0));
2870 110407 : }
2871 :
2872 0 : void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind,
2873 : DeoptimizeReason reason,
2874 : Node* value) {
2875 16280 : EmitDeoptimize(kArchDeoptimize, 0, nullptr, 0, nullptr, kind, reason, value);
2876 0 : }
2877 :
2878 0 : void InstructionSelector::VisitThrow(Node* node) {
2879 : OperandGenerator g(this);
2880 40076 : Emit(kArchThrowTerminator, g.NoOutput());
2881 0 : }
2882 :
2883 0 : void InstructionSelector::VisitDebugBreak(Node* node) {
2884 : OperandGenerator g(this);
2885 9087 : Emit(kArchDebugBreak, g.NoOutput());
2886 0 : }
2887 :
2888 0 : void InstructionSelector::VisitComment(Node* node) {
2889 : OperandGenerator g(this);
2890 0 : InstructionOperand operand(g.UseImmediate(node));
2891 0 : Emit(kArchComment, 0, nullptr, 1, &operand);
2892 0 : }
2893 :
2894 0 : void InstructionSelector::VisitUnsafePointerAdd(Node* node) {
2895 : #if V8_TARGET_ARCH_64_BIT
2896 3661 : VisitInt64Add(node);
2897 : #else // V8_TARGET_ARCH_64_BIT
2898 : VisitInt32Add(node);
2899 : #endif // V8_TARGET_ARCH_64_BIT
2900 0 : }
2901 :
2902 6514 : void InstructionSelector::VisitRetain(Node* node) {
2903 : OperandGenerator g(this);
2904 6514 : Emit(kArchNop, g.NoOutput(), g.UseAny(node->InputAt(0)));
2905 6514 : }
2906 :
2907 2007 : bool InstructionSelector::CanProduceSignalingNaN(Node* node) {
2908 : // TODO(jarin) Improve the heuristic here.
2909 3805 : if (node->opcode() == IrOpcode::kFloat64Add ||
2910 3796 : node->opcode() == IrOpcode::kFloat64Sub ||
2911 : node->opcode() == IrOpcode::kFloat64Mul) {
2912 : return false;
2913 : }
2914 0 : return true;
2915 : }
2916 :
2917 2916610 : FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
2918 : Node* state) {
2919 : DCHECK(state->opcode() == IrOpcode::kFrameState);
2920 : DCHECK_EQ(kFrameStateInputCount, state->InputCount());
2921 2916610 : FrameStateInfo state_info = OpParameter<FrameStateInfo>(state);
2922 :
2923 : int parameters = static_cast<int>(
2924 2916610 : StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size());
2925 : int locals = static_cast<int>(
2926 2916621 : StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size());
2927 : int stack = static_cast<int>(
2928 2916612 : StateValuesAccess(state->InputAt(kFrameStateStackInput)).size());
2929 :
2930 : DCHECK_EQ(parameters, state_info.parameter_count());
2931 : DCHECK_EQ(locals, state_info.local_count());
2932 :
2933 : FrameStateDescriptor* outer_state = nullptr;
2934 2916620 : Node* outer_node = state->InputAt(kFrameStateOuterStateInput);
2935 2916620 : if (outer_node->opcode() == IrOpcode::kFrameState) {
2936 220236 : outer_state = GetFrameStateDescriptor(outer_node);
2937 : }
2938 :
2939 : return new (instruction_zone()) FrameStateDescriptor(
2940 : instruction_zone(), state_info.type(), state_info.bailout_id(),
2941 : state_info.state_combine(), parameters, locals, stack,
2942 5833248 : state_info.shared_info(), outer_state);
2943 : }
2944 :
2945 :
2946 : } // namespace compiler
2947 : } // namespace internal
2948 : } // namespace v8
|