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 :
19 : namespace v8 {
20 : namespace internal {
21 : namespace compiler {
22 :
23 1301759 : InstructionSelector::InstructionSelector(
24 : Zone* zone, size_t node_count, Linkage* linkage,
25 : InstructionSequence* sequence, Schedule* schedule,
26 : SourcePositionTable* source_positions, Frame* frame,
27 : SourcePositionMode source_position_mode, Features features,
28 : EnableScheduling enable_scheduling,
29 : EnableSerialization enable_serialization)
30 : : zone_(zone),
31 : linkage_(linkage),
32 : sequence_(sequence),
33 : source_positions_(source_positions),
34 : source_position_mode_(source_position_mode),
35 : features_(features),
36 : schedule_(schedule),
37 : current_block_(nullptr),
38 : instructions_(zone),
39 : defined_(node_count, false, zone),
40 : used_(node_count, false, zone),
41 : effect_level_(node_count, 0, zone),
42 : virtual_registers_(node_count,
43 : InstructionOperand::kInvalidVirtualRegister, zone),
44 : virtual_register_rename_(zone),
45 : scheduler_(nullptr),
46 : enable_scheduling_(enable_scheduling),
47 : enable_serialization_(enable_serialization),
48 : frame_(frame),
49 2603553 : instruction_selection_failed_(false) {
50 1301794 : instructions_.reserve(node_count);
51 1301792 : }
52 :
53 28693833 : bool InstructionSelector::SelectInstructions() {
54 : // Mark the inputs of all phis in loop headers as used.
55 : BasicBlockVector* blocks = schedule()->rpo_order();
56 15648903 : for (auto const block : *blocks) {
57 13045347 : if (!block->IsLoopHeader()) continue;
58 : DCHECK_LE(2u, block->PredecessorCount());
59 1414697 : for (Node* const phi : *block) {
60 1137403 : if (phi->opcode() != IrOpcode::kPhi) continue;
61 :
62 : // Mark all inputs as used.
63 1091466 : for (Node* const input : phi->inputs()) {
64 : MarkAsUsed(input);
65 : }
66 : }
67 : }
68 :
69 : // Visit each basic block in post order.
70 14346988 : for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) {
71 13045223 : VisitBlock(*i);
72 13045199 : if (instruction_selection_failed()) return false;
73 : }
74 :
75 : // Schedule the selected instructions.
76 1301765 : if (UseInstructionScheduling()) {
77 0 : scheduler_ = new (zone()) InstructionScheduler(zone(), sequence());
78 : }
79 :
80 41738775 : for (auto const block : *blocks) {
81 26090210 : InstructionBlock* instruction_block =
82 13045091 : sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
83 28943634 : for (size_t i = 0; i < instruction_block->phis().size(); i++) {
84 1426712 : UpdateRenamesInPhi(instruction_block->PhiAt(i));
85 : }
86 13045105 : size_t end = instruction_block->code_end();
87 13045105 : size_t start = instruction_block->code_start();
88 : DCHECK_LE(end, start);
89 13045105 : StartBlock(RpoNumber::FromInt(block->rpo_number()));
90 69507503 : while (start-- > end) {
91 86834528 : UpdateRenames(instructions_[start]);
92 43417351 : AddInstruction(instructions_[start]);
93 : }
94 13045120 : EndBlock(RpoNumber::FromInt(block->rpo_number()));
95 : }
96 : #if DEBUG
97 : sequence()->ValidateSSA();
98 : #endif
99 : return true;
100 : }
101 :
102 26090036 : void InstructionSelector::StartBlock(RpoNumber rpo) {
103 13045018 : if (UseInstructionScheduling()) {
104 : DCHECK_NOT_NULL(scheduler_);
105 0 : scheduler_->StartBlock(rpo);
106 : } else {
107 13045018 : sequence()->StartBlock(rpo);
108 : }
109 13045110 : }
110 :
111 :
112 26090184 : void InstructionSelector::EndBlock(RpoNumber rpo) {
113 13045092 : if (UseInstructionScheduling()) {
114 : DCHECK_NOT_NULL(scheduler_);
115 0 : scheduler_->EndBlock(rpo);
116 : } else {
117 13045092 : sequence()->EndBlock(rpo);
118 : }
119 13045012 : }
120 :
121 :
122 86834724 : void InstructionSelector::AddInstruction(Instruction* instr) {
123 43417362 : if (UseInstructionScheduling()) {
124 : DCHECK_NOT_NULL(scheduler_);
125 0 : scheduler_->AddInstruction(instr);
126 : } else {
127 43417362 : sequence()->AddInstruction(instr);
128 : }
129 43417300 : }
130 :
131 13035424 : Instruction* InstructionSelector::Emit(InstructionCode opcode,
132 : InstructionOperand output,
133 : size_t temp_count,
134 : InstructionOperand* temps) {
135 13035424 : size_t output_count = output.IsInvalid() ? 0 : 1;
136 13035424 : return Emit(opcode, output_count, &output, 0, nullptr, temp_count, temps);
137 : }
138 :
139 :
140 11135857 : Instruction* InstructionSelector::Emit(InstructionCode opcode,
141 : InstructionOperand output,
142 : InstructionOperand a, size_t temp_count,
143 : InstructionOperand* temps) {
144 11135857 : size_t output_count = output.IsInvalid() ? 0 : 1;
145 11135857 : return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
146 : }
147 :
148 :
149 1697948 : Instruction* InstructionSelector::Emit(InstructionCode opcode,
150 : InstructionOperand output,
151 : InstructionOperand a,
152 : InstructionOperand b, size_t temp_count,
153 : InstructionOperand* temps) {
154 1697948 : size_t output_count = output.IsInvalid() ? 0 : 1;
155 1697948 : InstructionOperand inputs[] = {a, b};
156 : size_t input_count = arraysize(inputs);
157 : return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
158 1697948 : temps);
159 : }
160 :
161 :
162 194714 : Instruction* InstructionSelector::Emit(InstructionCode opcode,
163 : InstructionOperand output,
164 : InstructionOperand a,
165 : InstructionOperand b,
166 : InstructionOperand c, size_t temp_count,
167 : InstructionOperand* temps) {
168 194714 : size_t output_count = output.IsInvalid() ? 0 : 1;
169 194714 : InstructionOperand inputs[] = {a, b, c};
170 : size_t input_count = arraysize(inputs);
171 : return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
172 194714 : temps);
173 : }
174 :
175 :
176 2586005 : Instruction* InstructionSelector::Emit(
177 : InstructionCode opcode, InstructionOperand output, InstructionOperand a,
178 : InstructionOperand b, InstructionOperand c, InstructionOperand d,
179 : size_t temp_count, InstructionOperand* temps) {
180 2586005 : size_t output_count = output.IsInvalid() ? 0 : 1;
181 2586005 : InstructionOperand inputs[] = {a, b, c, d};
182 : size_t input_count = arraysize(inputs);
183 : return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
184 2586005 : temps);
185 : }
186 :
187 :
188 54016 : Instruction* InstructionSelector::Emit(
189 : InstructionCode opcode, InstructionOperand output, InstructionOperand a,
190 : InstructionOperand b, InstructionOperand c, InstructionOperand d,
191 : InstructionOperand e, size_t temp_count, InstructionOperand* temps) {
192 54016 : size_t output_count = output.IsInvalid() ? 0 : 1;
193 54016 : InstructionOperand inputs[] = {a, b, c, d, e};
194 : size_t input_count = arraysize(inputs);
195 : return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
196 54016 : temps);
197 : }
198 :
199 :
200 0 : Instruction* InstructionSelector::Emit(
201 : InstructionCode opcode, InstructionOperand output, InstructionOperand a,
202 : InstructionOperand b, InstructionOperand c, InstructionOperand d,
203 : InstructionOperand e, InstructionOperand f, size_t temp_count,
204 : InstructionOperand* temps) {
205 0 : size_t output_count = output.IsInvalid() ? 0 : 1;
206 0 : InstructionOperand inputs[] = {a, b, c, d, e, f};
207 : size_t input_count = arraysize(inputs);
208 : return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
209 0 : temps);
210 : }
211 :
212 :
213 43417392 : Instruction* InstructionSelector::Emit(
214 : InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
215 : size_t input_count, InstructionOperand* inputs, size_t temp_count,
216 : InstructionOperand* temps) {
217 86834784 : if (output_count >= Instruction::kMaxOutputCount ||
218 86834696 : input_count >= Instruction::kMaxInputCount ||
219 : temp_count >= Instruction::kMaxTempCount) {
220 : set_instruction_selection_failed();
221 10 : return nullptr;
222 : }
223 :
224 : Instruction* instr =
225 : Instruction::New(instruction_zone(), opcode, output_count, outputs,
226 43417382 : input_count, inputs, temp_count, temps);
227 43417311 : return Emit(instr);
228 : }
229 :
230 :
231 0 : Instruction* InstructionSelector::Emit(Instruction* instr) {
232 43417372 : instructions_.push_back(instr);
233 43417311 : return instr;
234 : }
235 :
236 :
237 28221394 : bool InstructionSelector::CanCover(Node* user, Node* node) const {
238 : // 1. Both {user} and {node} must be in the same basic block.
239 15630457 : if (schedule()->block(node) != schedule()->block(user)) {
240 : return false;
241 : }
242 : // 2. Pure {node}s must be owned by the {user}.
243 6962017 : if (node->op()->HasProperty(Operator::kPure)) {
244 5628920 : return node->OwnedBy(user);
245 : }
246 : // 3. Impure {node}s must match the effect level of {user}.
247 1333097 : if (GetEffectLevel(node) != GetEffectLevel(user)) {
248 : return false;
249 : }
250 : // 4. Only {node} must have value edges pointing to {user}.
251 5815620 : for (Edge const edge : node->use_edges()) {
252 2356569 : if (edge.from() != user && NodeProperties::IsValueEdge(edge)) {
253 167438 : return false;
254 : }
255 : }
256 1102482 : return true;
257 : }
258 :
259 0 : bool InstructionSelector::IsOnlyUserOfNodeInSameBlock(Node* user,
260 0 : Node* node) const {
261 0 : BasicBlock* bb_user = schedule()->block(user);
262 0 : BasicBlock* bb_node = schedule()->block(node);
263 0 : if (bb_user != bb_node) return false;
264 0 : for (Edge const edge : node->use_edges()) {
265 : Node* from = edge.from();
266 0 : if ((from != user) && (schedule()->block(from) == bb_user)) {
267 : return false;
268 : }
269 : }
270 0 : return true;
271 : }
272 :
273 179652261 : void InstructionSelector::UpdateRenames(Instruction* instruction) {
274 272470140 : for (size_t i = 0; i < instruction->InputCount(); i++) {
275 92817741 : TryRename(instruction->InputAt(i));
276 : }
277 43417329 : }
278 :
279 1426704 : void InstructionSelector::UpdateRenamesInPhi(PhiInstruction* phi) {
280 9935382 : for (size_t i = 0; i < phi->operands().size(); i++) {
281 3540979 : int vreg = phi->operands()[i];
282 : int renamed = GetRename(vreg);
283 3540979 : if (vreg != renamed) {
284 64363 : phi->RenameInput(i, renamed);
285 : }
286 : }
287 1426712 : }
288 :
289 0 : int InstructionSelector::GetRename(int virtual_register) {
290 : int rename = virtual_register;
291 : while (true) {
292 113388674 : if (static_cast<size_t>(rename) >= virtual_register_rename_.size()) break;
293 11399895 : int next = virtual_register_rename_[rename];
294 11399895 : if (next == InstructionOperand::kInvalidVirtualRegister) {
295 : break;
296 : }
297 : rename = next;
298 : }
299 0 : return rename;
300 : }
301 :
302 92817770 : void InstructionSelector::TryRename(InstructionOperand* op) {
303 185635540 : if (!op->IsUnallocated()) return;
304 : UnallocatedOperand* unalloc = UnallocatedOperand::cast(op);
305 : int vreg = unalloc->virtual_register();
306 : int rename = GetRename(vreg);
307 52674630 : if (rename != vreg) {
308 414369 : *unalloc = UnallocatedOperand(*unalloc, rename);
309 : }
310 : }
311 :
312 268805 : void InstructionSelector::SetRename(const Node* node, const Node* rename) {
313 268805 : int vreg = GetVirtualRegister(node);
314 806457 : if (static_cast<size_t>(vreg) >= virtual_register_rename_.size()) {
315 237286 : int invalid = InstructionOperand::kInvalidVirtualRegister;
316 237286 : virtual_register_rename_.resize(vreg + 1, invalid);
317 : }
318 268823 : virtual_register_rename_[vreg] = GetVirtualRegister(rename);
319 268828 : }
320 :
321 133935803 : int InstructionSelector::GetVirtualRegister(const Node* node) {
322 : DCHECK_NOT_NULL(node);
323 106487549 : size_t const id = node->id();
324 : DCHECK_LT(id, virtual_registers_.size());
325 240423443 : int virtual_register = virtual_registers_[id];
326 106487549 : if (virtual_register == InstructionOperand::kInvalidVirtualRegister) {
327 27448254 : virtual_register = sequence()->NextVirtualRegister();
328 27448345 : virtual_registers_[id] = virtual_register;
329 : }
330 106487640 : 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 31195527 : bool InstructionSelector::IsDefined(Node* node) const {
348 : DCHECK_NOT_NULL(node);
349 31195527 : size_t const id = node->id();
350 : DCHECK_LT(id, defined_.size());
351 31862567 : return defined_[id];
352 : }
353 :
354 :
355 25097687 : void InstructionSelector::MarkAsDefined(Node* node) {
356 : DCHECK_NOT_NULL(node);
357 25097687 : size_t const id = node->id();
358 : DCHECK_LT(id, defined_.size());
359 25097687 : defined_[id] = true;
360 7416257 : }
361 :
362 :
363 130212762 : 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 68865389 : if (node->opcode() == IrOpcode::kRetain) return true;
368 68853265 : if (!node->op()->HasProperty(Operator::kEliminatable)) return true;
369 61347373 : size_t const id = node->id();
370 : DCHECK_LT(id, used_.size());
371 122694746 : return used_[id];
372 : }
373 :
374 :
375 61774954 : void InstructionSelector::MarkAsUsed(Node* node) {
376 : DCHECK_NOT_NULL(node);
377 61774954 : size_t const id = node->id();
378 : DCHECK_LT(id, used_.size());
379 61774954 : used_[id] = true;
380 20351302 : }
381 :
382 11873187 : int InstructionSelector::GetEffectLevel(Node* node) const {
383 : DCHECK_NOT_NULL(node);
384 11873187 : size_t const id = node->id();
385 : DCHECK_LT(id, effect_level_.size());
386 22413277 : return effect_level_[id];
387 : }
388 :
389 73911517 : void InstructionSelector::SetEffectLevel(Node* node, int effect_level) {
390 : DCHECK_NOT_NULL(node);
391 73911517 : size_t const id = node->id();
392 : DCHECK_LT(id, effect_level_.size());
393 147823034 : effect_level_[id] = effect_level;
394 0 : }
395 :
396 6035153 : bool InstructionSelector::CanAddressRelativeToRootsRegister() const {
397 10227594 : return enable_serialization_ == kDisableSerialization &&
398 6035153 : CanUseRootsRegister();
399 : }
400 :
401 6361866 : bool InstructionSelector::CanUseRootsRegister() const {
402 : return linkage()->GetIncomingDescriptor()->flags() &
403 2169425 : CallDescriptor::kCanUseRoots;
404 : }
405 :
406 0 : void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
407 4536697 : const InstructionOperand& op) {
408 : UnallocatedOperand unalloc = UnallocatedOperand::cast(op);
409 4536697 : sequence()->MarkAsRepresentation(rep, unalloc.virtual_register());
410 0 : }
411 :
412 :
413 15377357 : void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
414 15377431 : Node* node) {
415 30754788 : sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node));
416 15377470 : }
417 :
418 : namespace {
419 :
420 21376344 : InstructionOperand OperandForDeopt(Isolate* isolate, OperandGenerator* g,
421 21376333 : Node* input, FrameStateInputKind kind,
422 : MachineRepresentation rep) {
423 21376344 : if (rep == MachineRepresentation::kNone) {
424 11 : return g->TempImmediate(FrameStateDescriptor::kImpossibleValue);
425 : }
426 :
427 21376333 : switch (input->opcode()) {
428 : case IrOpcode::kInt32Constant:
429 : case IrOpcode::kInt64Constant:
430 : case IrOpcode::kNumberConstant:
431 : case IrOpcode::kFloat32Constant:
432 : case IrOpcode::kFloat64Constant:
433 737691 : return g->UseImmediate(input);
434 : case IrOpcode::kHeapConstant: {
435 4793699 : 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 4793699 : Handle<HeapObject> constant = OpParameter<Handle<HeapObject>>(input);
447 : Heap::RootListIndex root_index;
448 4793699 : 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 6913 : return InstructionOperand();
453 : }
454 :
455 4786786 : 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 15844943 : switch (kind) {
465 : case FrameStateInputKind::kStackSlot:
466 13401914 : return g->UseUniqueSlot(input);
467 : case FrameStateInputKind::kAny:
468 : // Currently deopts "wrap" other operations, so the deopt's inputs
469 : // are potentially needed until the end of the deoptimising code.
470 2443029 : return g->UseAnyAtEnd(input);
471 : }
472 : }
473 0 : UNREACHABLE();
474 : }
475 :
476 : } // namespace
477 :
478 : class StateObjectDeduplicator {
479 : public:
480 : explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {}
481 : static const size_t kNotDuplicated = SIZE_MAX;
482 :
483 99223 : size_t GetObjectId(Node* node) {
484 : DCHECK(node->opcode() == IrOpcode::kTypedObjectState ||
485 : node->opcode() == IrOpcode::kObjectId ||
486 : node->opcode() == IrOpcode::kArgumentsElementsState);
487 176056 : for (size_t i = 0; i < objects_.size(); ++i) {
488 118926 : if (objects_[i] == node) return i;
489 : // ObjectId nodes are the Turbofan way to express objects with the same
490 : // identity in the deopt info. So they should always be mapped to
491 : // previously appearing TypedObjectState nodes.
492 91444 : if (HasObjectId(objects_[i]) && HasObjectId(node) &&
493 60546 : ObjectIdOf(objects_[i]->op()) == ObjectIdOf(node->op())) {
494 : return i;
495 : }
496 : }
497 : DCHECK(node->opcode() == IrOpcode::kTypedObjectState ||
498 : node->opcode() == IrOpcode::kArgumentsElementsState);
499 : return kNotDuplicated;
500 : }
501 :
502 : size_t InsertObject(Node* node) {
503 : DCHECK(node->opcode() == IrOpcode::kTypedObjectState ||
504 : node->opcode() == IrOpcode::kObjectId ||
505 : node->opcode() == IrOpcode::kArgumentsElementsState);
506 57130 : size_t id = objects_.size();
507 77923 : objects_.push_back(node);
508 : return id;
509 : }
510 :
511 : private:
512 61171 : static bool HasObjectId(Node* node) {
513 61171 : return node->opcode() == IrOpcode::kTypedObjectState ||
514 : node->opcode() == IrOpcode::kObjectId;
515 : }
516 :
517 : ZoneVector<Node*> objects_;
518 : };
519 :
520 : // Returns the number of instruction operands added to inputs.
521 48450928 : size_t InstructionSelector::AddOperandToStateValueDescriptor(
522 : StateValueList* values, InstructionOperandVector* inputs,
523 21520522 : OperandGenerator* g, StateObjectDeduplicator* deduplicator, Node* input,
524 : MachineType type, FrameStateInputKind kind, Zone* zone) {
525 48450928 : if (input == nullptr) {
526 : values->PushOptimizedOut();
527 26987631 : return 0;
528 : }
529 :
530 21463392 : switch (input->opcode()) {
531 : case IrOpcode::kArgumentsElementsState: {
532 8973 : values->PushArgumentsElements(ArgumentsStateTypeOf(input->op()));
533 : // The elements backing store of an arguments object participates in the
534 : // duplicate object counting, but can itself never appear duplicated.
535 : DCHECK_EQ(StateObjectDeduplicator::kNotDuplicated,
536 : deduplicator->GetObjectId(input));
537 : deduplicator->InsertObject(input);
538 8973 : return 0;
539 : }
540 : case IrOpcode::kArgumentsLengthState: {
541 9276 : values->PushArgumentsLength(ArgumentsStateTypeOf(input->op()));
542 9276 : return 0;
543 : }
544 : case IrOpcode::kObjectState: {
545 0 : UNREACHABLE();
546 : }
547 : case IrOpcode::kTypedObjectState:
548 : case IrOpcode::kObjectId: {
549 68950 : size_t id = deduplicator->GetObjectId(input);
550 68950 : if (id == StateObjectDeduplicator::kNotDuplicated) {
551 : DCHECK_EQ(IrOpcode::kTypedObjectState, input->opcode());
552 : size_t entries = 0;
553 : id = deduplicator->InsertObject(input);
554 57130 : StateValueList* nested = values->PushRecursiveField(zone, id);
555 57130 : int const input_count = input->op()->ValueInputCount();
556 57130 : ZoneVector<MachineType> const* types = MachineTypesOf(input->op());
557 337685 : for (int i = 0; i < input_count; ++i) {
558 : entries += AddOperandToStateValueDescriptor(
559 280555 : nested, inputs, g, deduplicator, input->InputAt(i), types->at(i),
560 280555 : kind, zone);
561 : }
562 : return entries;
563 : } else {
564 : // Crankshaft counts duplicate objects for the running id, so we have
565 : // to push the input again.
566 : deduplicator->InsertObject(input);
567 : values->PushDuplicate(id);
568 11820 : return 0;
569 : }
570 : }
571 : default: {
572 : InstructionOperand op =
573 21376193 : OperandForDeopt(isolate(), g, input, kind, type.representation());
574 21376221 : if (op.kind() == InstructionOperand::INVALID) {
575 : // Invalid operand means the value is impossible or optimized-out.
576 : values->PushOptimizedOut();
577 6916 : return 0;
578 : } else {
579 21369308 : inputs->push_back(op);
580 : values->PushPlain(type);
581 21369452 : return 1;
582 : }
583 : }
584 : }
585 : }
586 :
587 :
588 : // Returns the number of instruction operands added to inputs.
589 3360377 : size_t InstructionSelector::AddInputsToFrameStateDescriptor(
590 6720771 : FrameStateDescriptor* descriptor, Node* state, OperandGenerator* g,
591 : StateObjectDeduplicator* deduplicator, InstructionOperandVector* inputs,
592 : FrameStateInputKind kind, Zone* zone) {
593 : DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
594 :
595 : size_t entries = 0;
596 : size_t initial_size = inputs->size();
597 : USE(initial_size); // initial_size is only used for debug.
598 :
599 3360377 : if (descriptor->outer_state()) {
600 : entries += AddInputsToFrameStateDescriptor(
601 : descriptor->outer_state(), state->InputAt(kFrameStateOuterStateInput),
602 272677 : g, deduplicator, inputs, kind, zone);
603 : }
604 :
605 : Node* parameters = state->InputAt(kFrameStateParametersInput);
606 : Node* locals = state->InputAt(kFrameStateLocalsInput);
607 : Node* stack = state->InputAt(kFrameStateStackInput);
608 : Node* context = state->InputAt(kFrameStateContextInput);
609 : Node* function = state->InputAt(kFrameStateFunctionInput);
610 :
611 : DCHECK_EQ(descriptor->parameters_count(),
612 : StateValuesAccess(parameters).size());
613 : DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
614 : DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
615 :
616 3360377 : StateValueList* values_descriptor = descriptor->GetStateValueDescriptors();
617 :
618 : DCHECK_EQ(values_descriptor->size(), 0u);
619 3360377 : values_descriptor->ReserveSize(descriptor->GetSize());
620 :
621 : entries += AddOperandToStateValueDescriptor(
622 : values_descriptor, inputs, g, deduplicator, function,
623 3360389 : MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
624 8116097 : for (StateValuesAccess::TypedNode input_node :
625 8116056 : StateValuesAccess(parameters)) {
626 : entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
627 : deduplicator, input_node.node,
628 8116034 : input_node.type, kind, zone);
629 : }
630 3360394 : if (descriptor->HasContext()) {
631 : entries += AddOperandToStateValueDescriptor(
632 : values_descriptor, inputs, g, deduplicator, context,
633 3261239 : MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
634 : }
635 60348685 : for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
636 : entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
637 : deduplicator, input_node.node,
638 30174168 : input_node.type, kind, zone);
639 : }
640 6517066 : for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
641 : entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
642 : deduplicator, input_node.node,
643 3258530 : input_node.type, kind, zone);
644 : }
645 : DCHECK_EQ(initial_size + entries, inputs->size());
646 3360397 : return entries;
647 : }
648 :
649 :
650 : // An internal helper class for generating the operands to calls.
651 : // TODO(bmeurer): Get rid of the CallBuffer business and make
652 : // InstructionSelector::VisitCall platform independent instead.
653 : struct CallBuffer {
654 14312007 : CallBuffer(Zone* zone, const CallDescriptor* descriptor,
655 14312028 : FrameStateDescriptor* frame_state)
656 : : descriptor(descriptor),
657 : frame_state_descriptor(frame_state),
658 : output_nodes(zone),
659 : outputs(zone),
660 : instruction_args(zone),
661 4770667 : pushed_nodes(zone) {
662 4770667 : output_nodes.reserve(descriptor->ReturnCount());
663 4770673 : outputs.reserve(descriptor->ReturnCount());
664 4770672 : pushed_nodes.reserve(input_count());
665 4770675 : instruction_args.reserve(input_count() + frame_state_value_count());
666 4770684 : }
667 :
668 :
669 : const CallDescriptor* descriptor;
670 : FrameStateDescriptor* frame_state_descriptor;
671 : NodeVector output_nodes;
672 : InstructionOperandVector outputs;
673 : InstructionOperandVector instruction_args;
674 : ZoneVector<PushParameter> pushed_nodes;
675 :
676 14312008 : size_t input_count() const { return descriptor->InputCount(); }
677 :
678 : size_t frame_state_count() const { return descriptor->FrameStateCount(); }
679 :
680 : size_t frame_state_value_count() const {
681 : return (frame_state_descriptor == nullptr)
682 : ? 0
683 2733726 : : (frame_state_descriptor->GetTotalSize() +
684 7504401 : 1); // Include deopt id.
685 : }
686 : };
687 :
688 :
689 : // TODO(bmeurer): Get rid of the CallBuffer business and make
690 : // InstructionSelector::VisitCall platform independent instead.
691 9541285 : void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
692 : CallBufferFlags flags,
693 2733714 : int stack_param_delta) {
694 : OperandGenerator g(this);
695 : DCHECK_LE(call->op()->ValueOutputCount(),
696 : static_cast<int>(buffer->descriptor->ReturnCount()));
697 : DCHECK_EQ(
698 : call->op()->ValueInputCount(),
699 : static_cast<int>(buffer->input_count() + buffer->frame_state_count()));
700 :
701 21582300 : if (buffer->descriptor->ReturnCount() > 0) {
702 : // Collect the projections that represent multiple outputs from this call.
703 4536164 : if (buffer->descriptor->ReturnCount() == 1) {
704 13611080 : buffer->output_nodes.push_back(call);
705 : } else {
706 4078 : buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), nullptr);
707 15412 : for (Edge const edge : call->use_edges()) {
708 5667 : if (!NodeProperties::IsValueEdge(edge)) continue;
709 : DCHECK_EQ(IrOpcode::kProjection, edge.from()->opcode());
710 2548 : size_t const index = ProjectionIndexOf(edge.from()->op());
711 : DCHECK_LT(index, buffer->output_nodes.size());
712 : DCHECK(!buffer->output_nodes[index]);
713 2548 : buffer->output_nodes[index] = edge.from();
714 : }
715 : }
716 :
717 : // Filter out the outputs that aren't live because no projection uses them.
718 : size_t outputs_needed_by_framestate =
719 4536165 : buffer->frame_state_descriptor == nullptr
720 : ? 0
721 : : buffer->frame_state_descriptor->state_combine()
722 4536165 : .ConsumedOutputCount();
723 18148814 : for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
724 4538201 : bool output_is_live = buffer->output_nodes[i] != nullptr ||
725 : i < outputs_needed_by_framestate;
726 4538201 : if (output_is_live) {
727 : MachineRepresentation rep =
728 4536663 : buffer->descriptor->GetReturnType(static_cast<int>(i))
729 : .representation();
730 : LinkageLocation location =
731 4536663 : buffer->descriptor->GetReturnLocation(static_cast<int>(i));
732 :
733 : Node* output = buffer->output_nodes[i];
734 : InstructionOperand op = output == nullptr
735 : ? g.TempLocation(location)
736 4536663 : : g.DefineAsLocation(output, location);
737 : MarkAsRepresentation(rep, op);
738 :
739 4536703 : buffer->outputs.push_back(op);
740 : }
741 : }
742 : }
743 :
744 : // The first argument is always the callee code.
745 9388356 : Node* callee = call->InputAt(0);
746 : bool call_code_immediate = (flags & kCallCodeImmediate) != 0;
747 : bool call_address_immediate = (flags & kCallAddressImmediate) != 0;
748 9541338 : switch (buffer->descriptor->kind()) {
749 : case CallDescriptor::kCallCodeObject:
750 : buffer->instruction_args.push_back(
751 4546100 : (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant)
752 : ? g.UseImmediate(callee)
753 13633097 : : g.UseRegister(callee));
754 4546073 : break;
755 : case CallDescriptor::kCallAddress:
756 : buffer->instruction_args.push_back(
757 71587 : (call_address_immediate &&
758 : callee->opcode() == IrOpcode::kExternalConstant)
759 : ? g.UseImmediate(callee)
760 183829 : : g.UseRegister(callee));
761 71587 : break;
762 : case CallDescriptor::kCallJSFunction:
763 : buffer->instruction_args.push_back(
764 305948 : g.UseLocation(callee, buffer->descriptor->GetInputLocation(0)));
765 152974 : break;
766 : }
767 : DCHECK_EQ(1u, buffer->instruction_args.size());
768 :
769 : // If the call needs a frame state, we insert the state information as
770 : // follows (n is the number of value inputs to the frame state):
771 : // arg 1 : deoptimization id.
772 : // arg 2 - arg (n + 1) : value inputs to the frame state.
773 : size_t frame_state_entries = 0;
774 : USE(frame_state_entries); // frame_state_entries is only used for debug.
775 4770644 : if (buffer->frame_state_descriptor != nullptr) {
776 : Node* frame_state =
777 5467428 : call->InputAt(static_cast<int>(buffer->descriptor->InputCount()));
778 :
779 : // If it was a syntactic tail call we need to drop the current frame and
780 : // all the frames on top of it that are either an arguments adaptor frame
781 : // or a tail caller frame.
782 2733714 : if (buffer->descriptor->SupportsTailCalls()) {
783 0 : frame_state = NodeProperties::GetFrameStateInput(frame_state);
784 : buffer->frame_state_descriptor =
785 0 : buffer->frame_state_descriptor->outer_state();
786 0 : while (buffer->frame_state_descriptor != nullptr &&
787 : buffer->frame_state_descriptor->type() ==
788 : FrameStateType::kArgumentsAdaptor) {
789 0 : frame_state = NodeProperties::GetFrameStateInput(frame_state);
790 : buffer->frame_state_descriptor =
791 0 : buffer->frame_state_descriptor->outer_state();
792 : }
793 : }
794 :
795 : int const state_id = sequence()->AddDeoptimizationEntry(
796 : buffer->frame_state_descriptor, DeoptimizeKind::kLazy,
797 5467428 : DeoptimizeReason::kNoReason);
798 5467437 : buffer->instruction_args.push_back(g.TempImmediate(state_id));
799 :
800 : StateObjectDeduplicator deduplicator(instruction_zone());
801 :
802 : frame_state_entries =
803 : 1 + AddInputsToFrameStateDescriptor(
804 : buffer->frame_state_descriptor, frame_state, &g, &deduplicator,
805 : &buffer->instruction_args, FrameStateInputKind::kStackSlot,
806 2733718 : instruction_zone());
807 :
808 : DCHECK_EQ(1 + frame_state_entries, buffer->instruction_args.size());
809 : }
810 :
811 : size_t input_count = static_cast<size_t>(buffer->input_count());
812 :
813 : // Split the arguments into pushed_nodes and instruction_args. Pushed
814 : // arguments require an explicit push instruction before the call and do
815 : // not appear as arguments to the call. Everything else ends up
816 : // as an InstructionOperand argument to the call.
817 4770658 : auto iter(call->inputs().begin());
818 : size_t pushed_count = 0;
819 4770658 : bool call_tail = (flags & kCallTail) != 0;
820 28492313 : for (size_t index = 0; index < input_count; ++iter, ++index) {
821 : DCHECK(iter != call->inputs().end());
822 : DCHECK_NE(IrOpcode::kFrameState, (*iter)->op()->opcode());
823 28492288 : if (index == 0) continue; // The first argument (callee) is already done.
824 :
825 18951004 : LinkageLocation location = buffer->descriptor->GetInputLocation(index);
826 18951029 : if (call_tail) {
827 : location = LinkageLocation::ConvertToTailCallerLocation(
828 : location, stack_param_delta);
829 : }
830 18951029 : InstructionOperand op = g.UseLocation(*iter, location);
831 18951107 : if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) {
832 3699944 : int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1;
833 11099834 : if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
834 1540452 : buffer->pushed_nodes.resize(stack_index + 1);
835 : }
836 3699946 : PushParameter parameter(*iter, buffer->descriptor->GetInputType(index));
837 3699946 : buffer->pushed_nodes[stack_index] = parameter;
838 : pushed_count++;
839 : } else {
840 15251163 : buffer->instruction_args.push_back(op);
841 : }
842 : }
843 : DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count -
844 : frame_state_entries);
845 4770667 : if (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK && call_tail &&
846 4770667 : stack_param_delta != 0) {
847 : // For tail calls that change the size of their parameter list and keep
848 : // their return address on the stack, move the return address to just above
849 : // the parameters.
850 : LinkageLocation saved_return_location =
851 : LinkageLocation::ForSavedCallerReturnAddress();
852 : InstructionOperand return_address =
853 : g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation(
854 : saved_return_location, stack_param_delta),
855 13799 : saved_return_location);
856 13799 : buffer->instruction_args.push_back(return_address);
857 : }
858 4770667 : }
859 :
860 21250459 : bool InstructionSelector::IsSourcePositionUsed(Node* node) {
861 21250459 : return (source_position_mode_ == kAllSourcePositions ||
862 6665379 : node->opcode() == IrOpcode::kCall ||
863 6665386 : node->opcode() == IrOpcode::kCallWithCallerSavedRegisters ||
864 6663486 : node->opcode() == IrOpcode::kTrapIf ||
865 6467697 : node->opcode() == IrOpcode::kTrapUnless ||
866 17649581 : node->opcode() == IrOpcode::kProtectedLoad ||
867 11185650 : node->opcode() == IrOpcode::kProtectedStore);
868 : }
869 :
870 52180922 : void InstructionSelector::VisitBlock(BasicBlock* block) {
871 : DCHECK(!current_block_);
872 13045286 : current_block_ = block;
873 : auto current_num_instructions = [&] {
874 : DCHECK_GE(kMaxInt, instructions_.size());
875 173737356 : return static_cast<int>(instructions_.size());
876 13045286 : };
877 : int current_block_end = current_num_instructions();
878 :
879 : int effect_level = 0;
880 162661332 : for (Node* const node : *block) {
881 : SetEffectLevel(node, effect_level);
882 134377067 : if (node->opcode() == IrOpcode::kStore ||
883 66091933 : node->opcode() == IrOpcode::kUnalignedStore ||
884 66038130 : node->opcode() == IrOpcode::kCheckedStore ||
885 61602430 : node->opcode() == IrOpcode::kCall ||
886 61602062 : node->opcode() == IrOpcode::kCallWithCallerSavedRegisters ||
887 129883676 : node->opcode() == IrOpcode::kProtectedLoad ||
888 : node->opcode() == IrOpcode::kProtectedStore) {
889 6688916 : ++effect_level;
890 : }
891 : }
892 :
893 : // We visit the control first, then the nodes in the block, so the block's
894 : // control input should be on the same effect level as the last node.
895 13045286 : if (block->control_input() != nullptr) {
896 : SetEffectLevel(block->control_input(), effect_level);
897 : }
898 :
899 43433857 : auto FinishEmittedInstructions = [&](Node* node, int instruction_start) {
900 48157154 : if (instruction_selection_failed()) return false;
901 86867874 : if (current_num_instructions() == instruction_start) return true;
902 : std::reverse(instructions_.begin() + instruction_start,
903 44035140 : instructions_.end());
904 39311843 : if (!node) return true;
905 33193215 : SourcePosition source_position = source_positions_->GetSourcePosition(node);
906 33193246 : if (source_position.IsKnown() && IsSourcePositionUsed(node)) {
907 4723297 : sequence()->SetSourcePosition(instructions_[instruction_start],
908 9446594 : source_position);
909 : }
910 : return true;
911 13045286 : };
912 :
913 : // Generate code for the block control "top down", but schedule the code
914 : // "bottom up".
915 13045286 : VisitControl(block);
916 13045146 : if (!FinishEmittedInstructions(block->control_input(), current_block_end))
917 10 : return;
918 :
919 : // Visit code in reverse control flow order, because architecture-specific
920 : // matching may cover more than one node at a time.
921 149614266 : for (auto node : base::Reversed(*block)) {
922 : // Skip nodes that are unused or already defined.
923 98813018 : if (!IsUsed(node) || IsDefined(node)) continue;
924 : // Generate code for this node "top down", but schedule the code "bottom
925 : // up".
926 : int current_node_end = current_num_instructions();
927 30389455 : VisitNode(node);
928 30389152 : if (!FinishEmittedInstructions(node, current_node_end)) return;
929 : }
930 :
931 : // We're done with the block.
932 : InstructionBlock* instruction_block =
933 13045204 : sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
934 26090316 : instruction_block->set_code_start(static_cast<int>(instructions_.size()));
935 : instruction_block->set_code_end(current_block_end);
936 :
937 13045158 : current_block_ = nullptr;
938 : }
939 :
940 :
941 13073845 : void InstructionSelector::VisitControl(BasicBlock* block) {
942 : #ifdef DEBUG
943 : // SSA deconstruction requires targets of branches not to have phis.
944 : // Edge split form guarantees this property, but is more strict.
945 : if (block->SuccessorCount() > 1) {
946 : for (BasicBlock* const successor : block->successors()) {
947 : for (Node* const node : *successor) {
948 : if (IrOpcode::IsPhiOpcode(node->opcode())) {
949 : std::ostringstream str;
950 : str << "You might have specified merged variables for a label with "
951 : << "only one predecessor." << std::endl
952 : << "# Current Block: " << *successor << std::endl
953 : << "# Node: " << *node;
954 : FATAL(str.str().c_str());
955 : }
956 : }
957 : }
958 : }
959 : #endif
960 :
961 51672 : Node* input = block->control_input();
962 13045257 : switch (block->control()) {
963 : case BasicBlock::kGoto:
964 6118918 : return VisitGoto(block->SuccessorAt(0));
965 : case BasicBlock::kCall: {
966 : DCHECK_EQ(IrOpcode::kCall, input->opcode());
967 : BasicBlock* success = block->SuccessorAt(0);
968 : BasicBlock* exception = block->SuccessorAt(1);
969 155527 : return VisitCall(input, exception), VisitGoto(success);
970 : }
971 : case BasicBlock::kTailCall: {
972 : DCHECK_EQ(IrOpcode::kTailCall, input->opcode());
973 186553 : return VisitTailCall(input);
974 : }
975 : case BasicBlock::kBranch: {
976 : DCHECK_EQ(IrOpcode::kBranch, input->opcode());
977 : BasicBlock* tbranch = block->SuccessorAt(0);
978 : BasicBlock* fbranch = block->SuccessorAt(1);
979 3610823 : if (tbranch == fbranch) return VisitGoto(tbranch);
980 3610823 : return VisitBranch(input, tbranch, fbranch);
981 : }
982 : case BasicBlock::kSwitch: {
983 : DCHECK_EQ(IrOpcode::kSwitch, input->opcode());
984 : SwitchInfo sw;
985 : // Last successor must be Default.
986 28588 : sw.default_branch = block->successors().back();
987 : DCHECK_EQ(IrOpcode::kIfDefault, sw.default_branch->front()->opcode());
988 : // All other successors must be cases.
989 28588 : sw.case_count = block->SuccessorCount() - 1;
990 28588 : sw.case_branches = &block->successors().front();
991 : // Determine case values and their min/max.
992 28588 : sw.case_values = zone()->NewArray<int32_t>(sw.case_count);
993 28588 : sw.min_value = std::numeric_limits<int32_t>::max();
994 28588 : sw.max_value = std::numeric_limits<int32_t>::min();
995 394813 : for (size_t index = 0; index < sw.case_count; ++index) {
996 366225 : BasicBlock* branch = sw.case_branches[index];
997 366225 : int32_t value = OpParameter<int32_t>(branch->front()->op());
998 366225 : sw.case_values[index] = value;
999 366225 : if (sw.min_value > value) sw.min_value = value;
1000 366225 : if (sw.max_value < value) sw.max_value = value;
1001 : }
1002 : DCHECK_LE(sw.min_value, sw.max_value);
1003 : // Note that {value_range} can be 0 if {min_value} is -2^31 and
1004 : // {max_value} is 2^31-1, so don't assume that it's non-zero below.
1005 28588 : sw.value_range = 1u + bit_cast<uint32_t>(sw.max_value) -
1006 28588 : bit_cast<uint32_t>(sw.min_value);
1007 28588 : return VisitSwitch(input, sw);
1008 : }
1009 : case BasicBlock::kReturn: {
1010 : DCHECK_EQ(IrOpcode::kReturn, input->opcode());
1011 1511024 : return VisitReturn(input);
1012 : }
1013 : case BasicBlock::kDeoptimize: {
1014 51672 : DeoptimizeParameters p = DeoptimizeParametersOf(input->op());
1015 : Node* value = input->InputAt(0);
1016 : return VisitDeoptimize(p.kind(), p.reason(), value);
1017 : }
1018 : case BasicBlock::kThrow:
1019 : DCHECK_EQ(IrOpcode::kThrow, input->opcode());
1020 : return VisitThrow(input);
1021 : case BasicBlock::kNone: {
1022 : // Exit block doesn't have control.
1023 : DCHECK_NULL(input);
1024 : break;
1025 : }
1026 : default:
1027 0 : UNREACHABLE();
1028 : break;
1029 : }
1030 : }
1031 :
1032 0 : void InstructionSelector::MarkPairProjectionsAsWord32(Node* node) {
1033 0 : Node* projection0 = NodeProperties::FindProjection(node, 0);
1034 0 : if (projection0) {
1035 : MarkAsWord32(projection0);
1036 : }
1037 0 : Node* projection1 = NodeProperties::FindProjection(node, 1);
1038 0 : if (projection1) {
1039 : MarkAsWord32(projection1);
1040 : }
1041 0 : }
1042 :
1043 32842959 : void InstructionSelector::VisitNode(Node* node) {
1044 : DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes.
1045 30389401 : switch (node->opcode()) {
1046 : case IrOpcode::kStart:
1047 : case IrOpcode::kLoop:
1048 : case IrOpcode::kEnd:
1049 : case IrOpcode::kBranch:
1050 : case IrOpcode::kIfTrue:
1051 : case IrOpcode::kIfFalse:
1052 : case IrOpcode::kIfSuccess:
1053 : case IrOpcode::kSwitch:
1054 : case IrOpcode::kIfValue:
1055 : case IrOpcode::kIfDefault:
1056 : case IrOpcode::kEffectPhi:
1057 : case IrOpcode::kMerge:
1058 : case IrOpcode::kTerminate:
1059 : case IrOpcode::kBeginRegion:
1060 : // No code needed for these graph artifacts.
1061 : return;
1062 : case IrOpcode::kIfException:
1063 138085 : return MarkAsReference(node), VisitIfException(node);
1064 : case IrOpcode::kFinishRegion:
1065 : return MarkAsReference(node), VisitFinishRegion(node);
1066 : case IrOpcode::kParameter: {
1067 : MachineType type =
1068 4907162 : linkage()->GetParameterType(ParameterIndexOf(node->op()));
1069 2453627 : MarkAsRepresentation(type.representation(), node);
1070 2453628 : return VisitParameter(node);
1071 : }
1072 : case IrOpcode::kOsrValue:
1073 24445 : return MarkAsReference(node), VisitOsrValue(node);
1074 : case IrOpcode::kPhi: {
1075 1426704 : MachineRepresentation rep = PhiRepresentationOf(node->op());
1076 1426701 : if (rep == MachineRepresentation::kNone) return;
1077 1426707 : MarkAsRepresentation(rep, node);
1078 1426717 : return VisitPhi(node);
1079 : }
1080 : case IrOpcode::kProjection:
1081 328333 : return VisitProjection(node);
1082 : case IrOpcode::kInt32Constant:
1083 : case IrOpcode::kInt64Constant:
1084 : case IrOpcode::kExternalConstant:
1085 : case IrOpcode::kRelocatableInt32Constant:
1086 : case IrOpcode::kRelocatableInt64Constant:
1087 3795979 : return VisitConstant(node);
1088 : case IrOpcode::kFloat32Constant:
1089 135894 : return MarkAsFloat32(node), VisitConstant(node);
1090 : case IrOpcode::kFloat64Constant:
1091 324579 : return MarkAsFloat64(node), VisitConstant(node);
1092 : case IrOpcode::kHeapConstant:
1093 3306222 : return MarkAsReference(node), VisitConstant(node);
1094 : case IrOpcode::kNumberConstant: {
1095 2506455 : double value = OpParameter<double>(node);
1096 2506455 : if (!IsSmiDouble(value)) MarkAsReference(node);
1097 2506455 : return VisitConstant(node);
1098 : }
1099 : case IrOpcode::kCall:
1100 4428199 : return VisitCall(node);
1101 : case IrOpcode::kCallWithCallerSavedRegisters:
1102 378 : return VisitCallWithCallerSavedRegisters(node);
1103 : case IrOpcode::kDeoptimizeIf:
1104 121561 : return VisitDeoptimizeIf(node);
1105 : case IrOpcode::kDeoptimizeUnless:
1106 180755 : return VisitDeoptimizeUnless(node);
1107 : case IrOpcode::kTrapIf:
1108 : return VisitTrapIf(node, static_cast<Runtime::FunctionId>(
1109 1895 : OpParameter<int32_t>(node->op())));
1110 : case IrOpcode::kTrapUnless:
1111 : return VisitTrapUnless(node, static_cast<Runtime::FunctionId>(
1112 195781 : OpParameter<int32_t>(node->op())));
1113 : case IrOpcode::kFrameState:
1114 : case IrOpcode::kStateValues:
1115 : case IrOpcode::kObjectState:
1116 : return;
1117 : case IrOpcode::kDebugAbort:
1118 0 : VisitDebugAbort(node);
1119 0 : return;
1120 : case IrOpcode::kDebugBreak:
1121 : VisitDebugBreak(node);
1122 : return;
1123 : case IrOpcode::kComment:
1124 0 : VisitComment(node);
1125 0 : return;
1126 : case IrOpcode::kRetain:
1127 12192 : VisitRetain(node);
1128 12192 : return;
1129 : case IrOpcode::kLoad: {
1130 3366105 : LoadRepresentation type = LoadRepresentationOf(node->op());
1131 3366096 : MarkAsRepresentation(type.representation(), node);
1132 3366107 : return VisitLoad(node);
1133 : }
1134 : case IrOpcode::kStore:
1135 2193373 : return VisitStore(node);
1136 : case IrOpcode::kProtectedStore:
1137 1525 : return VisitProtectedStore(node);
1138 : case IrOpcode::kWord32And:
1139 115838 : return MarkAsWord32(node), VisitWord32And(node);
1140 : case IrOpcode::kWord32Or:
1141 18738 : return MarkAsWord32(node), VisitWord32Or(node);
1142 : case IrOpcode::kWord32Xor:
1143 13127 : return MarkAsWord32(node), VisitWord32Xor(node);
1144 : case IrOpcode::kWord32Shl:
1145 13664 : return MarkAsWord32(node), VisitWord32Shl(node);
1146 : case IrOpcode::kWord32Shr:
1147 43213 : return MarkAsWord32(node), VisitWord32Shr(node);
1148 : case IrOpcode::kWord32Sar:
1149 13507 : return MarkAsWord32(node), VisitWord32Sar(node);
1150 : case IrOpcode::kWord32Ror:
1151 971 : return MarkAsWord32(node), VisitWord32Ror(node);
1152 : case IrOpcode::kWord32Equal:
1153 34549 : return VisitWord32Equal(node);
1154 : case IrOpcode::kWord32Clz:
1155 1856 : return MarkAsWord32(node), VisitWord32Clz(node);
1156 : case IrOpcode::kWord32Ctz:
1157 857 : return MarkAsWord32(node), VisitWord32Ctz(node);
1158 : case IrOpcode::kWord32ReverseBits:
1159 0 : return MarkAsWord32(node), VisitWord32ReverseBits(node);
1160 : case IrOpcode::kWord32ReverseBytes:
1161 0 : return MarkAsWord32(node), VisitWord32ReverseBytes(node);
1162 : case IrOpcode::kInt32AbsWithOverflow:
1163 0 : return MarkAsWord32(node), VisitInt32AbsWithOverflow(node);
1164 : case IrOpcode::kWord32Popcnt:
1165 157 : return MarkAsWord32(node), VisitWord32Popcnt(node);
1166 : case IrOpcode::kWord64Popcnt:
1167 49 : return MarkAsWord32(node), VisitWord64Popcnt(node);
1168 : case IrOpcode::kWord64And:
1169 188859 : return MarkAsWord64(node), VisitWord64And(node);
1170 : case IrOpcode::kWord64Or:
1171 38431 : return MarkAsWord64(node), VisitWord64Or(node);
1172 : case IrOpcode::kWord64Xor:
1173 444 : return MarkAsWord64(node), VisitWord64Xor(node);
1174 : case IrOpcode::kWord64Shl:
1175 282467 : return MarkAsWord64(node), VisitWord64Shl(node);
1176 : case IrOpcode::kWord64Shr:
1177 51279 : return MarkAsWord64(node), VisitWord64Shr(node);
1178 : case IrOpcode::kWord64Sar:
1179 67677 : return MarkAsWord64(node), VisitWord64Sar(node);
1180 : case IrOpcode::kWord64Ror:
1181 140 : return MarkAsWord64(node), VisitWord64Ror(node);
1182 : case IrOpcode::kWord64Clz:
1183 37 : return MarkAsWord64(node), VisitWord64Clz(node);
1184 : case IrOpcode::kWord64Ctz:
1185 27 : return MarkAsWord64(node), VisitWord64Ctz(node);
1186 : case IrOpcode::kWord64ReverseBits:
1187 0 : return MarkAsWord64(node), VisitWord64ReverseBits(node);
1188 : case IrOpcode::kWord64ReverseBytes:
1189 0 : return MarkAsWord64(node), VisitWord64ReverseBytes(node);
1190 : case IrOpcode::kInt64AbsWithOverflow:
1191 0 : return MarkAsWord64(node), VisitInt64AbsWithOverflow(node);
1192 : case IrOpcode::kWord64Equal:
1193 21328 : return VisitWord64Equal(node);
1194 : case IrOpcode::kInt32Add:
1195 191884 : return MarkAsWord32(node), VisitInt32Add(node);
1196 : case IrOpcode::kInt32AddWithOverflow:
1197 17405 : return MarkAsWord32(node), VisitInt32AddWithOverflow(node);
1198 : case IrOpcode::kInt32Sub:
1199 41022 : return MarkAsWord32(node), VisitInt32Sub(node);
1200 : case IrOpcode::kInt32SubWithOverflow:
1201 17405 : return VisitInt32SubWithOverflow(node);
1202 : case IrOpcode::kInt32Mul:
1203 36717 : return MarkAsWord32(node), VisitInt32Mul(node);
1204 : case IrOpcode::kInt32MulWithOverflow:
1205 17405 : return MarkAsWord32(node), VisitInt32MulWithOverflow(node);
1206 : case IrOpcode::kInt32MulHigh:
1207 4852 : return VisitInt32MulHigh(node);
1208 : case IrOpcode::kInt32Div:
1209 2408 : return MarkAsWord32(node), VisitInt32Div(node);
1210 : case IrOpcode::kInt32Mod:
1211 3086 : return MarkAsWord32(node), VisitInt32Mod(node);
1212 : case IrOpcode::kInt32LessThan:
1213 1736 : return VisitInt32LessThan(node);
1214 : case IrOpcode::kInt32LessThanOrEqual:
1215 1139 : return VisitInt32LessThanOrEqual(node);
1216 : case IrOpcode::kUint32Div:
1217 628 : return MarkAsWord32(node), VisitUint32Div(node);
1218 : case IrOpcode::kUint32LessThan:
1219 3737 : return VisitUint32LessThan(node);
1220 : case IrOpcode::kUint32LessThanOrEqual:
1221 2130 : return VisitUint32LessThanOrEqual(node);
1222 : case IrOpcode::kUint32Mod:
1223 539 : return MarkAsWord32(node), VisitUint32Mod(node);
1224 : case IrOpcode::kUint32MulHigh:
1225 630 : return VisitUint32MulHigh(node);
1226 : case IrOpcode::kInt64Add:
1227 997589 : return MarkAsWord64(node), VisitInt64Add(node);
1228 : case IrOpcode::kInt64AddWithOverflow:
1229 33620 : return MarkAsWord64(node), VisitInt64AddWithOverflow(node);
1230 : case IrOpcode::kInt64Sub:
1231 132447 : return MarkAsWord64(node), VisitInt64Sub(node);
1232 : case IrOpcode::kInt64SubWithOverflow:
1233 33620 : return MarkAsWord64(node), VisitInt64SubWithOverflow(node);
1234 : case IrOpcode::kInt64Mul:
1235 2414 : return MarkAsWord64(node), VisitInt64Mul(node);
1236 : case IrOpcode::kInt64Div:
1237 600 : return MarkAsWord64(node), VisitInt64Div(node);
1238 : case IrOpcode::kInt64Mod:
1239 428 : return MarkAsWord64(node), VisitInt64Mod(node);
1240 : case IrOpcode::kInt64LessThan:
1241 1195 : return VisitInt64LessThan(node);
1242 : case IrOpcode::kInt64LessThanOrEqual:
1243 650 : return VisitInt64LessThanOrEqual(node);
1244 : case IrOpcode::kUint64Div:
1245 448 : return MarkAsWord64(node), VisitUint64Div(node);
1246 : case IrOpcode::kUint64LessThan:
1247 428 : return VisitUint64LessThan(node);
1248 : case IrOpcode::kUint64LessThanOrEqual:
1249 412 : return VisitUint64LessThanOrEqual(node);
1250 : case IrOpcode::kUint64Mod:
1251 418 : return MarkAsWord64(node), VisitUint64Mod(node);
1252 : case IrOpcode::kBitcastTaggedToWord:
1253 0 : return MarkAsRepresentation(MachineType::PointerRepresentation(), node),
1254 : VisitBitcastTaggedToWord(node);
1255 : case IrOpcode::kBitcastWordToTagged:
1256 208750 : return MarkAsReference(node), VisitBitcastWordToTagged(node);
1257 : case IrOpcode::kBitcastWordToTaggedSigned:
1258 0 : return MarkAsRepresentation(MachineRepresentation::kTaggedSigned, node),
1259 0 : EmitIdentity(node);
1260 : case IrOpcode::kChangeFloat32ToFloat64:
1261 24509 : return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node);
1262 : case IrOpcode::kChangeInt32ToFloat64:
1263 299398 : return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node);
1264 : case IrOpcode::kChangeUint32ToFloat64:
1265 2552 : return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node);
1266 : case IrOpcode::kChangeFloat64ToInt32:
1267 7087 : return MarkAsWord32(node), VisitChangeFloat64ToInt32(node);
1268 : case IrOpcode::kChangeFloat64ToUint32:
1269 267 : return MarkAsWord32(node), VisitChangeFloat64ToUint32(node);
1270 : case IrOpcode::kChangeFloat64ToUint64:
1271 186 : return MarkAsWord64(node), VisitChangeFloat64ToUint64(node);
1272 : case IrOpcode::kFloat64SilenceNaN:
1273 : MarkAsFloat64(node);
1274 2063 : if (CanProduceSignalingNaN(node->InputAt(0))) {
1275 1825 : return VisitFloat64SilenceNaN(node);
1276 : } else {
1277 238 : return EmitIdentity(node);
1278 : }
1279 : case IrOpcode::kTruncateFloat64ToUint32:
1280 52 : return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node);
1281 : case IrOpcode::kTruncateFloat32ToInt32:
1282 271 : return MarkAsWord32(node), VisitTruncateFloat32ToInt32(node);
1283 : case IrOpcode::kTruncateFloat32ToUint32:
1284 67 : return MarkAsWord32(node), VisitTruncateFloat32ToUint32(node);
1285 : case IrOpcode::kTryTruncateFloat32ToInt64:
1286 74 : return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node);
1287 : case IrOpcode::kTryTruncateFloat64ToInt64:
1288 126 : return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node);
1289 : case IrOpcode::kTryTruncateFloat32ToUint64:
1290 74 : return MarkAsWord64(node), VisitTryTruncateFloat32ToUint64(node);
1291 : case IrOpcode::kTryTruncateFloat64ToUint64:
1292 84 : return MarkAsWord64(node), VisitTryTruncateFloat64ToUint64(node);
1293 : case IrOpcode::kChangeInt32ToInt64:
1294 62512 : return MarkAsWord64(node), VisitChangeInt32ToInt64(node);
1295 : case IrOpcode::kChangeUint32ToUint64:
1296 235897 : return MarkAsWord64(node), VisitChangeUint32ToUint64(node);
1297 : case IrOpcode::kTruncateFloat64ToFloat32:
1298 20636 : return MarkAsFloat32(node), VisitTruncateFloat64ToFloat32(node);
1299 : case IrOpcode::kTruncateFloat64ToWord32:
1300 45408 : return MarkAsWord32(node), VisitTruncateFloat64ToWord32(node);
1301 : case IrOpcode::kTruncateInt64ToInt32:
1302 302622 : return MarkAsWord32(node), VisitTruncateInt64ToInt32(node);
1303 : case IrOpcode::kRoundFloat64ToInt32:
1304 101570 : return MarkAsWord32(node), VisitRoundFloat64ToInt32(node);
1305 : case IrOpcode::kRoundInt64ToFloat32:
1306 47 : return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node);
1307 : case IrOpcode::kRoundInt32ToFloat32:
1308 565 : return MarkAsFloat32(node), VisitRoundInt32ToFloat32(node);
1309 : case IrOpcode::kRoundInt64ToFloat64:
1310 1055 : return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node);
1311 : case IrOpcode::kBitcastFloat32ToInt32:
1312 62785 : return MarkAsWord32(node), VisitBitcastFloat32ToInt32(node);
1313 : case IrOpcode::kRoundUint32ToFloat32:
1314 123 : return MarkAsFloat32(node), VisitRoundUint32ToFloat32(node);
1315 : case IrOpcode::kRoundUint64ToFloat32:
1316 47 : return MarkAsFloat64(node), VisitRoundUint64ToFloat32(node);
1317 : case IrOpcode::kRoundUint64ToFloat64:
1318 177 : return MarkAsFloat64(node), VisitRoundUint64ToFloat64(node);
1319 : case IrOpcode::kBitcastFloat64ToInt64:
1320 62390 : return MarkAsWord64(node), VisitBitcastFloat64ToInt64(node);
1321 : case IrOpcode::kBitcastInt32ToFloat32:
1322 219 : return MarkAsFloat32(node), VisitBitcastInt32ToFloat32(node);
1323 : case IrOpcode::kBitcastInt64ToFloat64:
1324 275 : return MarkAsFloat64(node), VisitBitcastInt64ToFloat64(node);
1325 : case IrOpcode::kFloat32Add:
1326 626 : return MarkAsFloat32(node), VisitFloat32Add(node);
1327 : case IrOpcode::kFloat32Sub:
1328 1605 : return MarkAsFloat32(node), VisitFloat32Sub(node);
1329 : case IrOpcode::kFloat32Neg:
1330 228 : return MarkAsFloat32(node), VisitFloat32Neg(node);
1331 : case IrOpcode::kFloat32Mul:
1332 571 : return MarkAsFloat32(node), VisitFloat32Mul(node);
1333 : case IrOpcode::kFloat32Div:
1334 502 : return MarkAsFloat32(node), VisitFloat32Div(node);
1335 : case IrOpcode::kFloat32Abs:
1336 87 : return MarkAsFloat32(node), VisitFloat32Abs(node);
1337 : case IrOpcode::kFloat32Sqrt:
1338 196 : return MarkAsFloat32(node), VisitFloat32Sqrt(node);
1339 : case IrOpcode::kFloat32Equal:
1340 144 : return VisitFloat32Equal(node);
1341 : case IrOpcode::kFloat32LessThan:
1342 162 : return VisitFloat32LessThan(node);
1343 : case IrOpcode::kFloat32LessThanOrEqual:
1344 159 : return VisitFloat32LessThanOrEqual(node);
1345 : case IrOpcode::kFloat32Max:
1346 61 : return MarkAsFloat32(node), VisitFloat32Max(node);
1347 : case IrOpcode::kFloat32Min:
1348 61 : return MarkAsFloat32(node), VisitFloat32Min(node);
1349 : case IrOpcode::kFloat64Add:
1350 60795 : return MarkAsFloat64(node), VisitFloat64Add(node);
1351 : case IrOpcode::kFloat64Sub:
1352 22632 : return MarkAsFloat64(node), VisitFloat64Sub(node);
1353 : case IrOpcode::kFloat64Neg:
1354 10096 : return MarkAsFloat64(node), VisitFloat64Neg(node);
1355 : case IrOpcode::kFloat64Mul:
1356 13860 : return MarkAsFloat64(node), VisitFloat64Mul(node);
1357 : case IrOpcode::kFloat64Div:
1358 11698 : return MarkAsFloat64(node), VisitFloat64Div(node);
1359 : case IrOpcode::kFloat64Mod:
1360 1365 : return MarkAsFloat64(node), VisitFloat64Mod(node);
1361 : case IrOpcode::kFloat64Min:
1362 301 : return MarkAsFloat64(node), VisitFloat64Min(node);
1363 : case IrOpcode::kFloat64Max:
1364 142 : return MarkAsFloat64(node), VisitFloat64Max(node);
1365 : case IrOpcode::kFloat64Abs:
1366 375 : return MarkAsFloat64(node), VisitFloat64Abs(node);
1367 : case IrOpcode::kFloat64Acos:
1368 : return MarkAsFloat64(node), VisitFloat64Acos(node);
1369 : case IrOpcode::kFloat64Acosh:
1370 : return MarkAsFloat64(node), VisitFloat64Acosh(node);
1371 : case IrOpcode::kFloat64Asin:
1372 : return MarkAsFloat64(node), VisitFloat64Asin(node);
1373 : case IrOpcode::kFloat64Asinh:
1374 : return MarkAsFloat64(node), VisitFloat64Asinh(node);
1375 : case IrOpcode::kFloat64Atan:
1376 : return MarkAsFloat64(node), VisitFloat64Atan(node);
1377 : case IrOpcode::kFloat64Atanh:
1378 : return MarkAsFloat64(node), VisitFloat64Atanh(node);
1379 : case IrOpcode::kFloat64Atan2:
1380 : return MarkAsFloat64(node), VisitFloat64Atan2(node);
1381 : case IrOpcode::kFloat64Cbrt:
1382 : return MarkAsFloat64(node), VisitFloat64Cbrt(node);
1383 : case IrOpcode::kFloat64Cos:
1384 : return MarkAsFloat64(node), VisitFloat64Cos(node);
1385 : case IrOpcode::kFloat64Cosh:
1386 : return MarkAsFloat64(node), VisitFloat64Cosh(node);
1387 : case IrOpcode::kFloat64Exp:
1388 : return MarkAsFloat64(node), VisitFloat64Exp(node);
1389 : case IrOpcode::kFloat64Expm1:
1390 : return MarkAsFloat64(node), VisitFloat64Expm1(node);
1391 : case IrOpcode::kFloat64Log:
1392 : return MarkAsFloat64(node), VisitFloat64Log(node);
1393 : case IrOpcode::kFloat64Log1p:
1394 : return MarkAsFloat64(node), VisitFloat64Log1p(node);
1395 : case IrOpcode::kFloat64Log10:
1396 : return MarkAsFloat64(node), VisitFloat64Log10(node);
1397 : case IrOpcode::kFloat64Log2:
1398 : return MarkAsFloat64(node), VisitFloat64Log2(node);
1399 : case IrOpcode::kFloat64Pow:
1400 : return MarkAsFloat64(node), VisitFloat64Pow(node);
1401 : case IrOpcode::kFloat64Sin:
1402 : return MarkAsFloat64(node), VisitFloat64Sin(node);
1403 : case IrOpcode::kFloat64Sinh:
1404 : return MarkAsFloat64(node), VisitFloat64Sinh(node);
1405 : case IrOpcode::kFloat64Sqrt:
1406 421 : return MarkAsFloat64(node), VisitFloat64Sqrt(node);
1407 : case IrOpcode::kFloat64Tan:
1408 : return MarkAsFloat64(node), VisitFloat64Tan(node);
1409 : case IrOpcode::kFloat64Tanh:
1410 : return MarkAsFloat64(node), VisitFloat64Tanh(node);
1411 : case IrOpcode::kFloat64Equal:
1412 3997 : return VisitFloat64Equal(node);
1413 : case IrOpcode::kFloat64LessThan:
1414 7387 : return VisitFloat64LessThan(node);
1415 : case IrOpcode::kFloat64LessThanOrEqual:
1416 1322 : return VisitFloat64LessThanOrEqual(node);
1417 : case IrOpcode::kFloat32RoundDown:
1418 56 : return MarkAsFloat32(node), VisitFloat32RoundDown(node);
1419 : case IrOpcode::kFloat64RoundDown:
1420 8585 : return MarkAsFloat64(node), VisitFloat64RoundDown(node);
1421 : case IrOpcode::kFloat32RoundUp:
1422 56 : return MarkAsFloat32(node), VisitFloat32RoundUp(node);
1423 : case IrOpcode::kFloat64RoundUp:
1424 5655 : return MarkAsFloat64(node), VisitFloat64RoundUp(node);
1425 : case IrOpcode::kFloat32RoundTruncate:
1426 363 : return MarkAsFloat32(node), VisitFloat32RoundTruncate(node);
1427 : case IrOpcode::kFloat64RoundTruncate:
1428 4027 : return MarkAsFloat64(node), VisitFloat64RoundTruncate(node);
1429 : case IrOpcode::kFloat64RoundTiesAway:
1430 0 : return MarkAsFloat64(node), VisitFloat64RoundTiesAway(node);
1431 : case IrOpcode::kFloat32RoundTiesEven:
1432 37 : return MarkAsFloat32(node), VisitFloat32RoundTiesEven(node);
1433 : case IrOpcode::kFloat64RoundTiesEven:
1434 532 : return MarkAsFloat64(node), VisitFloat64RoundTiesEven(node);
1435 : case IrOpcode::kFloat64ExtractLowWord32:
1436 5 : return MarkAsWord32(node), VisitFloat64ExtractLowWord32(node);
1437 : case IrOpcode::kFloat64ExtractHighWord32:
1438 72541 : return MarkAsWord32(node), VisitFloat64ExtractHighWord32(node);
1439 : case IrOpcode::kFloat64InsertLowWord32:
1440 5 : return MarkAsFloat64(node), VisitFloat64InsertLowWord32(node);
1441 : case IrOpcode::kFloat64InsertHighWord32:
1442 5 : return MarkAsFloat64(node), VisitFloat64InsertHighWord32(node);
1443 : case IrOpcode::kStackSlot:
1444 1177 : return VisitStackSlot(node);
1445 : case IrOpcode::kLoadStackPointer:
1446 62 : return VisitLoadStackPointer(node);
1447 : case IrOpcode::kLoadFramePointer:
1448 19989 : return VisitLoadFramePointer(node);
1449 : case IrOpcode::kLoadParentFramePointer:
1450 24681 : return VisitLoadParentFramePointer(node);
1451 : case IrOpcode::kUnalignedLoad: {
1452 : UnalignedLoadRepresentation type =
1453 0 : UnalignedLoadRepresentationOf(node->op());
1454 0 : MarkAsRepresentation(type.representation(), node);
1455 0 : return VisitUnalignedLoad(node);
1456 : }
1457 : case IrOpcode::kUnalignedStore:
1458 0 : return VisitUnalignedStore(node);
1459 : case IrOpcode::kCheckedLoad: {
1460 : MachineRepresentation rep =
1461 76214 : CheckedLoadRepresentationOf(node->op()).representation();
1462 76214 : MarkAsRepresentation(rep, node);
1463 76214 : return VisitCheckedLoad(node);
1464 : }
1465 : case IrOpcode::kCheckedStore:
1466 54016 : return VisitCheckedStore(node);
1467 : case IrOpcode::kInt32PairAdd:
1468 : MarkAsWord32(node);
1469 0 : MarkPairProjectionsAsWord32(node);
1470 0 : return VisitInt32PairAdd(node);
1471 : case IrOpcode::kInt32PairSub:
1472 : MarkAsWord32(node);
1473 0 : MarkPairProjectionsAsWord32(node);
1474 0 : return VisitInt32PairSub(node);
1475 : case IrOpcode::kInt32PairMul:
1476 : MarkAsWord32(node);
1477 0 : MarkPairProjectionsAsWord32(node);
1478 0 : return VisitInt32PairMul(node);
1479 : case IrOpcode::kWord32PairShl:
1480 : MarkAsWord32(node);
1481 0 : MarkPairProjectionsAsWord32(node);
1482 0 : return VisitWord32PairShl(node);
1483 : case IrOpcode::kWord32PairShr:
1484 : MarkAsWord32(node);
1485 0 : MarkPairProjectionsAsWord32(node);
1486 0 : return VisitWord32PairShr(node);
1487 : case IrOpcode::kWord32PairSar:
1488 : MarkAsWord32(node);
1489 0 : MarkPairProjectionsAsWord32(node);
1490 0 : return VisitWord32PairSar(node);
1491 : case IrOpcode::kAtomicLoad: {
1492 464 : LoadRepresentation type = LoadRepresentationOf(node->op());
1493 464 : MarkAsRepresentation(type.representation(), node);
1494 464 : return VisitAtomicLoad(node);
1495 : }
1496 : case IrOpcode::kAtomicStore:
1497 270 : return VisitAtomicStore(node);
1498 : #define ATOMIC_CASE(name) \
1499 : case IrOpcode::kAtomic##name: { \
1500 : MachineType type = AtomicOpRepresentationOf(node->op()); \
1501 : MarkAsRepresentation(type.representation(), node); \
1502 : return VisitAtomic##name(node); \
1503 : }
1504 420 : ATOMIC_CASE(Exchange)
1505 420 : ATOMIC_CASE(CompareExchange)
1506 420 : ATOMIC_CASE(Add)
1507 420 : ATOMIC_CASE(Sub)
1508 420 : ATOMIC_CASE(And)
1509 420 : ATOMIC_CASE(Or)
1510 420 : ATOMIC_CASE(Xor)
1511 : #undef ATOMIC_CASE
1512 : case IrOpcode::kProtectedLoad: {
1513 3764 : LoadRepresentation type = LoadRepresentationOf(node->op());
1514 3764 : MarkAsRepresentation(type.representation(), node);
1515 3765 : return VisitProtectedLoad(node);
1516 : }
1517 : case IrOpcode::kUnsafePointerAdd:
1518 6575 : MarkAsRepresentation(MachineType::PointerRepresentation(), node);
1519 : return VisitUnsafePointerAdd(node);
1520 : case IrOpcode::kF32x4Splat:
1521 0 : return MarkAsSimd128(node), VisitF32x4Splat(node);
1522 : case IrOpcode::kF32x4ExtractLane:
1523 0 : return MarkAsFloat32(node), VisitF32x4ExtractLane(node);
1524 : case IrOpcode::kF32x4ReplaceLane:
1525 0 : return MarkAsSimd128(node), VisitF32x4ReplaceLane(node);
1526 : case IrOpcode::kF32x4SConvertI32x4:
1527 0 : return MarkAsSimd128(node), VisitF32x4SConvertI32x4(node);
1528 : case IrOpcode::kF32x4UConvertI32x4:
1529 0 : return MarkAsSimd128(node), VisitF32x4UConvertI32x4(node);
1530 : case IrOpcode::kF32x4Abs:
1531 0 : return MarkAsSimd128(node), VisitF32x4Abs(node);
1532 : case IrOpcode::kF32x4Neg:
1533 0 : return MarkAsSimd128(node), VisitF32x4Neg(node);
1534 : case IrOpcode::kF32x4RecipApprox:
1535 0 : return MarkAsSimd128(node), VisitF32x4RecipApprox(node);
1536 : case IrOpcode::kF32x4RecipSqrtApprox:
1537 0 : return MarkAsSimd128(node), VisitF32x4RecipSqrtApprox(node);
1538 : case IrOpcode::kF32x4Add:
1539 0 : return MarkAsSimd128(node), VisitF32x4Add(node);
1540 : case IrOpcode::kF32x4AddHoriz:
1541 0 : return MarkAsSimd128(node), VisitF32x4AddHoriz(node);
1542 : case IrOpcode::kF32x4Sub:
1543 0 : return MarkAsSimd128(node), VisitF32x4Sub(node);
1544 : case IrOpcode::kF32x4Mul:
1545 0 : return MarkAsSimd128(node), VisitF32x4Mul(node);
1546 : case IrOpcode::kF32x4Min:
1547 0 : return MarkAsSimd128(node), VisitF32x4Min(node);
1548 : case IrOpcode::kF32x4Max:
1549 0 : return MarkAsSimd128(node), VisitF32x4Max(node);
1550 : case IrOpcode::kF32x4Eq:
1551 0 : return MarkAsSimd128(node), VisitF32x4Eq(node);
1552 : case IrOpcode::kF32x4Ne:
1553 0 : return MarkAsSimd128(node), VisitF32x4Ne(node);
1554 : case IrOpcode::kF32x4Lt:
1555 0 : return MarkAsSimd128(node), VisitF32x4Lt(node);
1556 : case IrOpcode::kF32x4Le:
1557 0 : return MarkAsSimd128(node), VisitF32x4Le(node);
1558 : case IrOpcode::kI32x4Splat:
1559 354 : return MarkAsSimd128(node), VisitI32x4Splat(node);
1560 : case IrOpcode::kI32x4ExtractLane:
1561 840 : return MarkAsWord32(node), VisitI32x4ExtractLane(node);
1562 : case IrOpcode::kI32x4ReplaceLane:
1563 78 : return MarkAsSimd128(node), VisitI32x4ReplaceLane(node);
1564 : case IrOpcode::kI32x4SConvertF32x4:
1565 0 : return MarkAsSimd128(node), VisitI32x4SConvertF32x4(node);
1566 : case IrOpcode::kI32x4SConvertI16x8Low:
1567 0 : return MarkAsSimd128(node), VisitI32x4SConvertI16x8Low(node);
1568 : case IrOpcode::kI32x4SConvertI16x8High:
1569 0 : return MarkAsSimd128(node), VisitI32x4SConvertI16x8High(node);
1570 : case IrOpcode::kI32x4Neg:
1571 6 : return MarkAsSimd128(node), VisitI32x4Neg(node);
1572 : case IrOpcode::kI32x4Shl:
1573 6 : return MarkAsSimd128(node), VisitI32x4Shl(node);
1574 : case IrOpcode::kI32x4ShrS:
1575 6 : return MarkAsSimd128(node), VisitI32x4ShrS(node);
1576 : case IrOpcode::kI32x4Add:
1577 12 : return MarkAsSimd128(node), VisitI32x4Add(node);
1578 : case IrOpcode::kI32x4AddHoriz:
1579 6 : return MarkAsSimd128(node), VisitI32x4AddHoriz(node);
1580 : case IrOpcode::kI32x4Sub:
1581 6 : return MarkAsSimd128(node), VisitI32x4Sub(node);
1582 : case IrOpcode::kI32x4Mul:
1583 6 : return MarkAsSimd128(node), VisitI32x4Mul(node);
1584 : case IrOpcode::kI32x4MinS:
1585 6 : return MarkAsSimd128(node), VisitI32x4MinS(node);
1586 : case IrOpcode::kI32x4MaxS:
1587 6 : return MarkAsSimd128(node), VisitI32x4MaxS(node);
1588 : case IrOpcode::kI32x4Eq:
1589 6 : return MarkAsSimd128(node), VisitI32x4Eq(node);
1590 : case IrOpcode::kI32x4Ne:
1591 12 : return MarkAsSimd128(node), VisitI32x4Ne(node);
1592 : case IrOpcode::kI32x4GtS:
1593 12 : return MarkAsSimd128(node), VisitI32x4GtS(node);
1594 : case IrOpcode::kI32x4GeS:
1595 12 : return MarkAsSimd128(node), VisitI32x4GeS(node);
1596 : case IrOpcode::kI32x4UConvertF32x4:
1597 0 : return MarkAsSimd128(node), VisitI32x4UConvertF32x4(node);
1598 : case IrOpcode::kI32x4UConvertI16x8Low:
1599 0 : return MarkAsSimd128(node), VisitI32x4UConvertI16x8Low(node);
1600 : case IrOpcode::kI32x4UConvertI16x8High:
1601 0 : return MarkAsSimd128(node), VisitI32x4UConvertI16x8High(node);
1602 : case IrOpcode::kI32x4ShrU:
1603 6 : return MarkAsSimd128(node), VisitI32x4ShrU(node);
1604 : case IrOpcode::kI32x4MinU:
1605 6 : return MarkAsSimd128(node), VisitI32x4MinU(node);
1606 : case IrOpcode::kI32x4MaxU:
1607 6 : return MarkAsSimd128(node), VisitI32x4MaxU(node);
1608 : case IrOpcode::kI32x4GtU:
1609 12 : return MarkAsSimd128(node), VisitI32x4GtU(node);
1610 : case IrOpcode::kI32x4GeU:
1611 12 : return MarkAsSimd128(node), VisitI32x4GeU(node);
1612 : case IrOpcode::kI16x8Splat:
1613 324 : return MarkAsSimd128(node), VisitI16x8Splat(node);
1614 : case IrOpcode::kI16x8ExtractLane:
1615 1680 : return MarkAsWord32(node), VisitI16x8ExtractLane(node);
1616 : case IrOpcode::kI16x8ReplaceLane:
1617 72 : return MarkAsSimd128(node), VisitI16x8ReplaceLane(node);
1618 : case IrOpcode::kI16x8SConvertI8x16Low:
1619 0 : return MarkAsSimd128(node), VisitI16x8SConvertI8x16Low(node);
1620 : case IrOpcode::kI16x8SConvertI8x16High:
1621 0 : return MarkAsSimd128(node), VisitI16x8SConvertI8x16High(node);
1622 : case IrOpcode::kI16x8Neg:
1623 6 : return MarkAsSimd128(node), VisitI16x8Neg(node);
1624 : case IrOpcode::kI16x8Shl:
1625 6 : return MarkAsSimd128(node), VisitI16x8Shl(node);
1626 : case IrOpcode::kI16x8ShrS:
1627 6 : return MarkAsSimd128(node), VisitI16x8ShrS(node);
1628 : case IrOpcode::kI16x8SConvertI32x4:
1629 0 : return MarkAsSimd128(node), VisitI16x8SConvertI32x4(node);
1630 : case IrOpcode::kI16x8Add:
1631 6 : return MarkAsSimd128(node), VisitI16x8Add(node);
1632 : case IrOpcode::kI16x8AddSaturateS:
1633 6 : return MarkAsSimd128(node), VisitI16x8AddSaturateS(node);
1634 : case IrOpcode::kI16x8AddHoriz:
1635 6 : return MarkAsSimd128(node), VisitI16x8AddHoriz(node);
1636 : case IrOpcode::kI16x8Sub:
1637 6 : return MarkAsSimd128(node), VisitI16x8Sub(node);
1638 : case IrOpcode::kI16x8SubSaturateS:
1639 6 : return MarkAsSimd128(node), VisitI16x8SubSaturateS(node);
1640 : case IrOpcode::kI16x8Mul:
1641 6 : return MarkAsSimd128(node), VisitI16x8Mul(node);
1642 : case IrOpcode::kI16x8MinS:
1643 6 : return MarkAsSimd128(node), VisitI16x8MinS(node);
1644 : case IrOpcode::kI16x8MaxS:
1645 6 : return MarkAsSimd128(node), VisitI16x8MaxS(node);
1646 : case IrOpcode::kI16x8Eq:
1647 6 : return MarkAsSimd128(node), VisitI16x8Eq(node);
1648 : case IrOpcode::kI16x8Ne:
1649 12 : return MarkAsSimd128(node), VisitI16x8Ne(node);
1650 : case IrOpcode::kI16x8GtS:
1651 12 : return MarkAsSimd128(node), VisitI16x8GtS(node);
1652 : case IrOpcode::kI16x8GeS:
1653 12 : return MarkAsSimd128(node), VisitI16x8GeS(node);
1654 : case IrOpcode::kI16x8UConvertI8x16Low:
1655 0 : return MarkAsSimd128(node), VisitI16x8UConvertI8x16Low(node);
1656 : case IrOpcode::kI16x8UConvertI8x16High:
1657 0 : return MarkAsSimd128(node), VisitI16x8UConvertI8x16High(node);
1658 : case IrOpcode::kI16x8ShrU:
1659 6 : return MarkAsSimd128(node), VisitI16x8ShrU(node);
1660 : case IrOpcode::kI16x8UConvertI32x4:
1661 0 : return MarkAsSimd128(node), VisitI16x8UConvertI32x4(node);
1662 : case IrOpcode::kI16x8AddSaturateU:
1663 6 : return MarkAsSimd128(node), VisitI16x8AddSaturateU(node);
1664 : case IrOpcode::kI16x8SubSaturateU:
1665 6 : return MarkAsSimd128(node), VisitI16x8SubSaturateU(node);
1666 : case IrOpcode::kI16x8MinU:
1667 6 : return MarkAsSimd128(node), VisitI16x8MinU(node);
1668 : case IrOpcode::kI16x8MaxU:
1669 6 : return MarkAsSimd128(node), VisitI16x8MaxU(node);
1670 : case IrOpcode::kI16x8GtU:
1671 12 : return MarkAsSimd128(node), VisitI16x8GtU(node);
1672 : case IrOpcode::kI16x8GeU:
1673 12 : return MarkAsSimd128(node), VisitI16x8GeU(node);
1674 : case IrOpcode::kI8x16Splat:
1675 294 : return MarkAsSimd128(node), VisitI8x16Splat(node);
1676 : case IrOpcode::kI8x16ExtractLane:
1677 3648 : return MarkAsWord32(node), VisitI8x16ExtractLane(node);
1678 : case IrOpcode::kI8x16ReplaceLane:
1679 120 : return MarkAsSimd128(node), VisitI8x16ReplaceLane(node);
1680 : case IrOpcode::kI8x16Neg:
1681 6 : return MarkAsSimd128(node), VisitI8x16Neg(node);
1682 : case IrOpcode::kI8x16Shl:
1683 0 : return MarkAsSimd128(node), VisitI8x16Shl(node);
1684 : case IrOpcode::kI8x16ShrS:
1685 0 : return MarkAsSimd128(node), VisitI8x16ShrS(node);
1686 : case IrOpcode::kI8x16SConvertI16x8:
1687 0 : return MarkAsSimd128(node), VisitI8x16SConvertI16x8(node);
1688 : case IrOpcode::kI8x16Add:
1689 6 : return MarkAsSimd128(node), VisitI8x16Add(node);
1690 : case IrOpcode::kI8x16AddSaturateS:
1691 6 : return MarkAsSimd128(node), VisitI8x16AddSaturateS(node);
1692 : case IrOpcode::kI8x16Sub:
1693 6 : return MarkAsSimd128(node), VisitI8x16Sub(node);
1694 : case IrOpcode::kI8x16SubSaturateS:
1695 6 : return MarkAsSimd128(node), VisitI8x16SubSaturateS(node);
1696 : case IrOpcode::kI8x16Mul:
1697 0 : return MarkAsSimd128(node), VisitI8x16Mul(node);
1698 : case IrOpcode::kI8x16MinS:
1699 6 : return MarkAsSimd128(node), VisitI8x16MinS(node);
1700 : case IrOpcode::kI8x16MaxS:
1701 6 : return MarkAsSimd128(node), VisitI8x16MaxS(node);
1702 : case IrOpcode::kI8x16Eq:
1703 6 : return MarkAsSimd128(node), VisitI8x16Eq(node);
1704 : case IrOpcode::kI8x16Ne:
1705 12 : return MarkAsSimd128(node), VisitI8x16Ne(node);
1706 : case IrOpcode::kI8x16GtS:
1707 12 : return MarkAsSimd128(node), VisitI8x16GtS(node);
1708 : case IrOpcode::kI8x16GeS:
1709 12 : return MarkAsSimd128(node), VisitI8x16GeS(node);
1710 : case IrOpcode::kI8x16ShrU:
1711 0 : return MarkAsSimd128(node), VisitI8x16ShrU(node);
1712 : case IrOpcode::kI8x16UConvertI16x8:
1713 0 : return MarkAsSimd128(node), VisitI8x16UConvertI16x8(node);
1714 : case IrOpcode::kI8x16AddSaturateU:
1715 6 : return MarkAsSimd128(node), VisitI8x16AddSaturateU(node);
1716 : case IrOpcode::kI8x16SubSaturateU:
1717 6 : return MarkAsSimd128(node), VisitI8x16SubSaturateU(node);
1718 : case IrOpcode::kI8x16MinU:
1719 6 : return MarkAsSimd128(node), VisitI8x16MinU(node);
1720 : case IrOpcode::kI8x16MaxU:
1721 6 : return MarkAsSimd128(node), VisitI8x16MaxU(node);
1722 : case IrOpcode::kI8x16GtU:
1723 12 : return MarkAsSimd128(node), VisitI8x16GtU(node);
1724 : case IrOpcode::kI8x16GeU:
1725 12 : return MarkAsSimd128(node), VisitI16x8GeU(node);
1726 : case IrOpcode::kS128Zero:
1727 0 : return MarkAsSimd128(node), VisitS128Zero(node);
1728 : case IrOpcode::kS128And:
1729 6 : return MarkAsSimd128(node), VisitS128And(node);
1730 : case IrOpcode::kS128Or:
1731 6 : return MarkAsSimd128(node), VisitS128Or(node);
1732 : case IrOpcode::kS128Xor:
1733 6 : return MarkAsSimd128(node), VisitS128Xor(node);
1734 : case IrOpcode::kS128Not:
1735 6 : return MarkAsSimd128(node), VisitS128Not(node);
1736 : case IrOpcode::kS128Select:
1737 36 : return MarkAsSimd128(node), VisitS128Select(node);
1738 : case IrOpcode::kS8x16Shuffle:
1739 0 : return MarkAsSimd128(node), VisitS8x16Shuffle(node);
1740 : case IrOpcode::kS1x4AnyTrue:
1741 0 : return MarkAsWord32(node), VisitS1x4AnyTrue(node);
1742 : case IrOpcode::kS1x4AllTrue:
1743 0 : return MarkAsWord32(node), VisitS1x4AllTrue(node);
1744 : case IrOpcode::kS1x8AnyTrue:
1745 0 : return MarkAsWord32(node), VisitS1x8AnyTrue(node);
1746 : case IrOpcode::kS1x8AllTrue:
1747 0 : return MarkAsWord32(node), VisitS1x8AllTrue(node);
1748 : case IrOpcode::kS1x16AnyTrue:
1749 0 : return MarkAsWord32(node), VisitS1x16AnyTrue(node);
1750 : case IrOpcode::kS1x16AllTrue:
1751 0 : return MarkAsWord32(node), VisitS1x16AllTrue(node);
1752 : default:
1753 : V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d",
1754 0 : node->opcode(), node->op()->mnemonic(), node->id());
1755 : break;
1756 : }
1757 : }
1758 :
1759 62 : void InstructionSelector::VisitLoadStackPointer(Node* node) {
1760 : OperandGenerator g(this);
1761 62 : Emit(kArchStackPointer, g.DefineAsRegister(node));
1762 62 : }
1763 :
1764 19989 : void InstructionSelector::VisitLoadFramePointer(Node* node) {
1765 : OperandGenerator g(this);
1766 19989 : Emit(kArchFramePointer, g.DefineAsRegister(node));
1767 19989 : }
1768 :
1769 24681 : void InstructionSelector::VisitLoadParentFramePointer(Node* node) {
1770 : OperandGenerator g(this);
1771 24681 : Emit(kArchParentFramePointer, g.DefineAsRegister(node));
1772 24681 : }
1773 :
1774 0 : void InstructionSelector::VisitFloat64Acos(Node* node) {
1775 68 : VisitFloat64Ieee754Unop(node, kIeee754Float64Acos);
1776 0 : }
1777 :
1778 0 : void InstructionSelector::VisitFloat64Acosh(Node* node) {
1779 67 : VisitFloat64Ieee754Unop(node, kIeee754Float64Acosh);
1780 0 : }
1781 :
1782 0 : void InstructionSelector::VisitFloat64Asin(Node* node) {
1783 68 : VisitFloat64Ieee754Unop(node, kIeee754Float64Asin);
1784 0 : }
1785 :
1786 0 : void InstructionSelector::VisitFloat64Asinh(Node* node) {
1787 67 : VisitFloat64Ieee754Unop(node, kIeee754Float64Asinh);
1788 0 : }
1789 :
1790 0 : void InstructionSelector::VisitFloat64Atan(Node* node) {
1791 81 : VisitFloat64Ieee754Unop(node, kIeee754Float64Atan);
1792 0 : }
1793 :
1794 0 : void InstructionSelector::VisitFloat64Atanh(Node* node) {
1795 67 : VisitFloat64Ieee754Unop(node, kIeee754Float64Atanh);
1796 0 : }
1797 :
1798 0 : void InstructionSelector::VisitFloat64Atan2(Node* node) {
1799 91 : VisitFloat64Ieee754Binop(node, kIeee754Float64Atan2);
1800 0 : }
1801 :
1802 0 : void InstructionSelector::VisitFloat64Cbrt(Node* node) {
1803 67 : VisitFloat64Ieee754Unop(node, kIeee754Float64Cbrt);
1804 0 : }
1805 :
1806 0 : void InstructionSelector::VisitFloat64Cos(Node* node) {
1807 256 : VisitFloat64Ieee754Unop(node, kIeee754Float64Cos);
1808 0 : }
1809 :
1810 0 : void InstructionSelector::VisitFloat64Cosh(Node* node) {
1811 75 : VisitFloat64Ieee754Unop(node, kIeee754Float64Cosh);
1812 0 : }
1813 :
1814 0 : void InstructionSelector::VisitFloat64Exp(Node* node) {
1815 81 : VisitFloat64Ieee754Unop(node, kIeee754Float64Exp);
1816 0 : }
1817 :
1818 0 : void InstructionSelector::VisitFloat64Expm1(Node* node) {
1819 67 : VisitFloat64Ieee754Unop(node, kIeee754Float64Expm1);
1820 0 : }
1821 :
1822 0 : void InstructionSelector::VisitFloat64Log(Node* node) {
1823 232 : VisitFloat64Ieee754Unop(node, kIeee754Float64Log);
1824 0 : }
1825 :
1826 0 : void InstructionSelector::VisitFloat64Log1p(Node* node) {
1827 67 : VisitFloat64Ieee754Unop(node, kIeee754Float64Log1p);
1828 0 : }
1829 :
1830 0 : void InstructionSelector::VisitFloat64Log2(Node* node) {
1831 67 : VisitFloat64Ieee754Unop(node, kIeee754Float64Log2);
1832 0 : }
1833 :
1834 0 : void InstructionSelector::VisitFloat64Log10(Node* node) {
1835 67 : VisitFloat64Ieee754Unop(node, kIeee754Float64Log10);
1836 0 : }
1837 :
1838 0 : void InstructionSelector::VisitFloat64Pow(Node* node) {
1839 140 : VisitFloat64Ieee754Binop(node, kIeee754Float64Pow);
1840 0 : }
1841 :
1842 0 : void InstructionSelector::VisitFloat64Sin(Node* node) {
1843 256 : VisitFloat64Ieee754Unop(node, kIeee754Float64Sin);
1844 0 : }
1845 :
1846 0 : void InstructionSelector::VisitFloat64Sinh(Node* node) {
1847 75 : VisitFloat64Ieee754Unop(node, kIeee754Float64Sinh);
1848 0 : }
1849 :
1850 0 : void InstructionSelector::VisitFloat64Tan(Node* node) {
1851 81 : VisitFloat64Ieee754Unop(node, kIeee754Float64Tan);
1852 0 : }
1853 :
1854 0 : void InstructionSelector::VisitFloat64Tanh(Node* node) {
1855 75 : VisitFloat64Ieee754Unop(node, kIeee754Float64Tanh);
1856 0 : }
1857 :
1858 7807 : void InstructionSelector::EmitTableSwitch(const SwitchInfo& sw,
1859 7807 : InstructionOperand& index_operand) {
1860 : OperandGenerator g(this);
1861 7807 : size_t input_count = 2 + sw.value_range;
1862 : DCHECK_LE(sw.value_range, std::numeric_limits<size_t>::max() - 2);
1863 : auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
1864 7807 : inputs[0] = index_operand;
1865 7807 : InstructionOperand default_operand = g.Label(sw.default_branch);
1866 7807 : std::fill(&inputs[1], &inputs[input_count], default_operand);
1867 310676 : for (size_t index = 0; index < sw.case_count; ++index) {
1868 310676 : size_t value = sw.case_values[index] - sw.min_value;
1869 310676 : BasicBlock* branch = sw.case_branches[index];
1870 : DCHECK_LE(0u, value);
1871 : DCHECK_LT(value + 2, input_count);
1872 310676 : inputs[value + 2] = g.Label(branch);
1873 : }
1874 7807 : Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
1875 7807 : }
1876 :
1877 :
1878 20781 : void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw,
1879 20781 : InstructionOperand& value_operand) {
1880 : OperandGenerator g(this);
1881 20781 : size_t input_count = 2 + sw.case_count * 2;
1882 : DCHECK_LE(sw.case_count, (std::numeric_limits<size_t>::max() - 2) / 2);
1883 : auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
1884 20781 : inputs[0] = value_operand;
1885 20781 : inputs[1] = g.Label(sw.default_branch);
1886 97111 : for (size_t index = 0; index < sw.case_count; ++index) {
1887 55549 : int32_t value = sw.case_values[index];
1888 55549 : BasicBlock* branch = sw.case_branches[index];
1889 55549 : inputs[index * 2 + 2 + 0] = g.TempImmediate(value);
1890 55549 : inputs[index * 2 + 2 + 1] = g.Label(branch);
1891 : }
1892 20781 : Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
1893 20781 : }
1894 :
1895 :
1896 0 : void InstructionSelector::VisitBitcastTaggedToWord(Node* node) {
1897 0 : EmitIdentity(node);
1898 0 : }
1899 :
1900 208750 : void InstructionSelector::VisitBitcastWordToTagged(Node* node) {
1901 : OperandGenerator g(this);
1902 208750 : Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(node->InputAt(0)));
1903 208754 : }
1904 :
1905 : // 32 bit targets do not implement the following instructions.
1906 : #if V8_TARGET_ARCH_32_BIT
1907 :
1908 : void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
1909 :
1910 :
1911 : void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); }
1912 :
1913 :
1914 : void InstructionSelector::VisitWord64Xor(Node* node) { UNIMPLEMENTED(); }
1915 :
1916 :
1917 : void InstructionSelector::VisitWord64Shl(Node* node) { UNIMPLEMENTED(); }
1918 :
1919 :
1920 : void InstructionSelector::VisitWord64Shr(Node* node) { UNIMPLEMENTED(); }
1921 :
1922 :
1923 : void InstructionSelector::VisitWord64Sar(Node* node) { UNIMPLEMENTED(); }
1924 :
1925 :
1926 : void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); }
1927 :
1928 :
1929 : void InstructionSelector::VisitWord64Clz(Node* node) { UNIMPLEMENTED(); }
1930 :
1931 :
1932 : void InstructionSelector::VisitWord64Ctz(Node* node) { UNIMPLEMENTED(); }
1933 :
1934 :
1935 : void InstructionSelector::VisitWord64ReverseBits(Node* node) {
1936 : UNIMPLEMENTED();
1937 : }
1938 :
1939 :
1940 : void InstructionSelector::VisitWord64Popcnt(Node* node) { UNIMPLEMENTED(); }
1941 :
1942 :
1943 : void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); }
1944 :
1945 :
1946 : void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
1947 :
1948 :
1949 : void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
1950 : UNIMPLEMENTED();
1951 : }
1952 :
1953 :
1954 : void InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); }
1955 :
1956 :
1957 : void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
1958 : UNIMPLEMENTED();
1959 : }
1960 :
1961 : void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); }
1962 :
1963 :
1964 : void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); }
1965 :
1966 :
1967 : void InstructionSelector::VisitInt64LessThan(Node* node) { UNIMPLEMENTED(); }
1968 :
1969 :
1970 : void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
1971 : UNIMPLEMENTED();
1972 : }
1973 :
1974 :
1975 : void InstructionSelector::VisitUint64Div(Node* node) { UNIMPLEMENTED(); }
1976 :
1977 :
1978 : void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
1979 :
1980 :
1981 : void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); }
1982 :
1983 :
1984 : void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
1985 : UNIMPLEMENTED();
1986 : }
1987 :
1988 :
1989 : void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); }
1990 :
1991 :
1992 : void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
1993 : UNIMPLEMENTED();
1994 : }
1995 :
1996 :
1997 : void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
1998 : UNIMPLEMENTED();
1999 : }
2000 :
2001 : void InstructionSelector::VisitChangeFloat64ToUint64(Node* node) {
2002 : UNIMPLEMENTED();
2003 : }
2004 :
2005 : void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
2006 : UNIMPLEMENTED();
2007 : }
2008 :
2009 :
2010 : void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
2011 : UNIMPLEMENTED();
2012 : }
2013 :
2014 :
2015 : void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
2016 : UNIMPLEMENTED();
2017 : }
2018 :
2019 :
2020 : void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
2021 : UNIMPLEMENTED();
2022 : }
2023 :
2024 :
2025 : void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
2026 : UNIMPLEMENTED();
2027 : }
2028 :
2029 :
2030 : void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
2031 : UNIMPLEMENTED();
2032 : }
2033 :
2034 :
2035 : void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
2036 : UNIMPLEMENTED();
2037 : }
2038 :
2039 :
2040 : void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
2041 : UNIMPLEMENTED();
2042 : }
2043 :
2044 :
2045 : void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
2046 : UNIMPLEMENTED();
2047 : }
2048 :
2049 : void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
2050 : UNIMPLEMENTED();
2051 : }
2052 :
2053 :
2054 : void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
2055 : UNIMPLEMENTED();
2056 : }
2057 : #endif // V8_TARGET_ARCH_32_BIT
2058 :
2059 : // 64 bit targets do not implement the following instructions.
2060 : #if V8_TARGET_ARCH_64_BIT
2061 0 : void InstructionSelector::VisitInt32PairAdd(Node* node) { UNIMPLEMENTED(); }
2062 :
2063 0 : void InstructionSelector::VisitInt32PairSub(Node* node) { UNIMPLEMENTED(); }
2064 :
2065 0 : void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); }
2066 :
2067 0 : void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); }
2068 :
2069 0 : void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); }
2070 :
2071 0 : void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); }
2072 : #endif // V8_TARGET_ARCH_64_BIT
2073 :
2074 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2075 : !V8_TARGET_ARCH_MIPS64
2076 0 : void InstructionSelector::VisitF32x4Splat(Node* node) { UNIMPLEMENTED(); }
2077 :
2078 0 : void InstructionSelector::VisitF32x4ExtractLane(Node* node) { UNIMPLEMENTED(); }
2079 :
2080 0 : void InstructionSelector::VisitF32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2081 :
2082 0 : void InstructionSelector::VisitF32x4SConvertI32x4(Node* node) {
2083 0 : UNIMPLEMENTED();
2084 : }
2085 :
2086 0 : void InstructionSelector::VisitF32x4UConvertI32x4(Node* node) {
2087 0 : UNIMPLEMENTED();
2088 : }
2089 :
2090 0 : void InstructionSelector::VisitF32x4Abs(Node* node) { UNIMPLEMENTED(); }
2091 :
2092 0 : void InstructionSelector::VisitF32x4Neg(Node* node) { UNIMPLEMENTED(); }
2093 :
2094 0 : void InstructionSelector::VisitF32x4RecipSqrtApprox(Node* node) {
2095 0 : UNIMPLEMENTED();
2096 : }
2097 :
2098 0 : void InstructionSelector::VisitF32x4Add(Node* node) { UNIMPLEMENTED(); }
2099 :
2100 0 : void InstructionSelector::VisitF32x4AddHoriz(Node* node) { UNIMPLEMENTED(); }
2101 :
2102 0 : void InstructionSelector::VisitF32x4Sub(Node* node) { UNIMPLEMENTED(); }
2103 :
2104 0 : void InstructionSelector::VisitF32x4Mul(Node* node) { UNIMPLEMENTED(); }
2105 :
2106 0 : void InstructionSelector::VisitF32x4Max(Node* node) { UNIMPLEMENTED(); }
2107 :
2108 0 : void InstructionSelector::VisitF32x4Min(Node* node) { UNIMPLEMENTED(); }
2109 :
2110 0 : void InstructionSelector::VisitF32x4RecipApprox(Node* node) { UNIMPLEMENTED(); }
2111 :
2112 0 : void InstructionSelector::VisitF32x4Eq(Node* node) { UNIMPLEMENTED(); }
2113 :
2114 0 : void InstructionSelector::VisitF32x4Ne(Node* node) { UNIMPLEMENTED(); }
2115 :
2116 0 : void InstructionSelector::VisitF32x4Lt(Node* node) { UNIMPLEMENTED(); }
2117 :
2118 0 : void InstructionSelector::VisitF32x4Le(Node* node) { UNIMPLEMENTED(); }
2119 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS
2120 : // && !V8_TARGET_ARCH_MIPS64
2121 :
2122 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64 && \
2123 : !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2124 : void InstructionSelector::VisitI32x4Splat(Node* node) { UNIMPLEMENTED(); }
2125 :
2126 : void InstructionSelector::VisitI32x4ExtractLane(Node* node) { UNIMPLEMENTED(); }
2127 :
2128 : void InstructionSelector::VisitI32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2129 :
2130 : void InstructionSelector::VisitI32x4Add(Node* node) { UNIMPLEMENTED(); }
2131 :
2132 : void InstructionSelector::VisitI32x4Sub(Node* node) { UNIMPLEMENTED(); }
2133 :
2134 : void InstructionSelector::VisitI32x4Shl(Node* node) { UNIMPLEMENTED(); }
2135 :
2136 : void InstructionSelector::VisitI32x4ShrS(Node* node) { UNIMPLEMENTED(); }
2137 :
2138 : void InstructionSelector::VisitI32x4Mul(Node* node) { UNIMPLEMENTED(); }
2139 :
2140 : void InstructionSelector::VisitI32x4MaxS(Node* node) { UNIMPLEMENTED(); }
2141 :
2142 : void InstructionSelector::VisitI32x4MinS(Node* node) { UNIMPLEMENTED(); }
2143 :
2144 : void InstructionSelector::VisitI32x4Eq(Node* node) { UNIMPLEMENTED(); }
2145 :
2146 : void InstructionSelector::VisitI32x4Ne(Node* node) { UNIMPLEMENTED(); }
2147 :
2148 : void InstructionSelector::VisitI32x4MinU(Node* node) { UNIMPLEMENTED(); }
2149 :
2150 : void InstructionSelector::VisitI32x4MaxU(Node* node) { UNIMPLEMENTED(); }
2151 :
2152 : void InstructionSelector::VisitI32x4ShrU(Node* node) { UNIMPLEMENTED(); }
2153 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64
2154 : // && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_MIPS
2155 : // && !V8_TARGET_ARCH_MIPS64
2156 :
2157 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64 && \
2158 : !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2159 : void InstructionSelector::VisitI32x4AddHoriz(Node* node) { UNIMPLEMENTED(); }
2160 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64
2161 : // && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2162 :
2163 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2164 : !V8_TARGET_ARCH_MIPS64
2165 0 : void InstructionSelector::VisitI32x4SConvertF32x4(Node* node) {
2166 0 : UNIMPLEMENTED();
2167 : }
2168 :
2169 0 : void InstructionSelector::VisitI32x4UConvertF32x4(Node* node) {
2170 0 : UNIMPLEMENTED();
2171 : }
2172 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS
2173 : // && !V8_TARGET_ARCH_MIPS64
2174 :
2175 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2176 : !V8_TARGET_ARCH_MIPS64
2177 0 : void InstructionSelector::VisitI32x4SConvertI16x8Low(Node* node) {
2178 0 : UNIMPLEMENTED();
2179 : }
2180 :
2181 0 : void InstructionSelector::VisitI32x4SConvertI16x8High(Node* node) {
2182 0 : UNIMPLEMENTED();
2183 : }
2184 :
2185 0 : void InstructionSelector::VisitI32x4UConvertI16x8Low(Node* node) {
2186 0 : UNIMPLEMENTED();
2187 : }
2188 :
2189 0 : void InstructionSelector::VisitI32x4UConvertI16x8High(Node* node) {
2190 0 : UNIMPLEMENTED();
2191 : }
2192 :
2193 0 : void InstructionSelector::VisitI16x8SConvertI8x16Low(Node* node) {
2194 0 : UNIMPLEMENTED();
2195 : }
2196 :
2197 0 : void InstructionSelector::VisitI16x8SConvertI8x16High(Node* node) {
2198 0 : UNIMPLEMENTED();
2199 : }
2200 :
2201 0 : void InstructionSelector::VisitI16x8SConvertI32x4(Node* node) {
2202 0 : UNIMPLEMENTED();
2203 : }
2204 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS
2205 : // && !V8_TARGET_ARCH_MIPS64
2206 :
2207 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64 && \
2208 : !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2209 : void InstructionSelector::VisitI32x4Neg(Node* node) { UNIMPLEMENTED(); }
2210 :
2211 : void InstructionSelector::VisitI32x4GtS(Node* node) { UNIMPLEMENTED(); }
2212 :
2213 : void InstructionSelector::VisitI32x4GeS(Node* node) { UNIMPLEMENTED(); }
2214 :
2215 : void InstructionSelector::VisitI32x4GtU(Node* node) { UNIMPLEMENTED(); }
2216 :
2217 : void InstructionSelector::VisitI32x4GeU(Node* node) { UNIMPLEMENTED(); }
2218 :
2219 : void InstructionSelector::VisitI16x8Splat(Node* node) { UNIMPLEMENTED(); }
2220 :
2221 : void InstructionSelector::VisitI16x8ExtractLane(Node* node) { UNIMPLEMENTED(); }
2222 :
2223 : void InstructionSelector::VisitI16x8ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2224 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64
2225 : // && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_MIPS &&
2226 : // !V8_TARGET_ARCH_MIPS64
2227 :
2228 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64 && \
2229 : !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2230 : void InstructionSelector::VisitI16x8Shl(Node* node) { UNIMPLEMENTED(); }
2231 :
2232 : void InstructionSelector::VisitI16x8ShrS(Node* node) { UNIMPLEMENTED(); }
2233 :
2234 : void InstructionSelector::VisitI16x8ShrU(Node* node) { UNIMPLEMENTED(); }
2235 :
2236 : void InstructionSelector::VisitI16x8Add(Node* node) { UNIMPLEMENTED(); }
2237 :
2238 : void InstructionSelector::VisitI16x8AddSaturateS(Node* node) {
2239 : UNIMPLEMENTED();
2240 : }
2241 :
2242 : void InstructionSelector::VisitI16x8Sub(Node* node) { UNIMPLEMENTED(); }
2243 :
2244 : void InstructionSelector::VisitI16x8SubSaturateS(Node* node) {
2245 : UNIMPLEMENTED();
2246 : }
2247 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64
2248 : // && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2249 :
2250 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64 && \
2251 : !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2252 : void InstructionSelector::VisitI16x8AddHoriz(Node* node) { UNIMPLEMENTED(); }
2253 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64
2254 : // && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2255 :
2256 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64 && \
2257 : !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2258 : void InstructionSelector::VisitI16x8Mul(Node* node) { UNIMPLEMENTED(); }
2259 :
2260 : void InstructionSelector::VisitI16x8MinS(Node* node) { UNIMPLEMENTED(); }
2261 :
2262 : void InstructionSelector::VisitI16x8MaxS(Node* node) { UNIMPLEMENTED(); }
2263 :
2264 : void InstructionSelector::VisitI16x8Eq(Node* node) { UNIMPLEMENTED(); }
2265 :
2266 : void InstructionSelector::VisitI16x8Ne(Node* node) { UNIMPLEMENTED(); }
2267 :
2268 : void InstructionSelector::VisitI16x8AddSaturateU(Node* node) {
2269 : UNIMPLEMENTED();
2270 : }
2271 :
2272 : void InstructionSelector::VisitI16x8SubSaturateU(Node* node) {
2273 : UNIMPLEMENTED();
2274 : }
2275 :
2276 : void InstructionSelector::VisitI16x8MinU(Node* node) { UNIMPLEMENTED(); }
2277 :
2278 : void InstructionSelector::VisitI16x8MaxU(Node* node) { UNIMPLEMENTED(); }
2279 :
2280 : void InstructionSelector::VisitI16x8Neg(Node* node) { UNIMPLEMENTED(); }
2281 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64
2282 : // && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2283 :
2284 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2285 : !V8_TARGET_ARCH_MIPS64
2286 0 : void InstructionSelector::VisitI16x8UConvertI32x4(Node* node) {
2287 0 : UNIMPLEMENTED();
2288 : }
2289 :
2290 0 : void InstructionSelector::VisitI16x8UConvertI8x16Low(Node* node) {
2291 0 : UNIMPLEMENTED();
2292 : }
2293 :
2294 0 : void InstructionSelector::VisitI16x8UConvertI8x16High(Node* node) {
2295 0 : UNIMPLEMENTED();
2296 : }
2297 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS
2298 : // && !V8_TARGET_ARCH_MIPS64
2299 :
2300 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64 && \
2301 : !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2302 : void InstructionSelector::VisitI16x8GtS(Node* node) { UNIMPLEMENTED(); }
2303 :
2304 : void InstructionSelector::VisitI16x8GeS(Node* node) { UNIMPLEMENTED(); }
2305 :
2306 : void InstructionSelector::VisitI16x8GtU(Node* node) { UNIMPLEMENTED(); }
2307 :
2308 : void InstructionSelector::VisitI16x8GeU(Node* node) { UNIMPLEMENTED(); }
2309 :
2310 : void InstructionSelector::VisitI8x16Neg(Node* node) { UNIMPLEMENTED(); }
2311 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64
2312 : // && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2313 :
2314 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2315 : !V8_TARGET_ARCH_MIPS64
2316 0 : void InstructionSelector::VisitI8x16Shl(Node* node) { UNIMPLEMENTED(); }
2317 :
2318 0 : void InstructionSelector::VisitI8x16ShrS(Node* node) { UNIMPLEMENTED(); }
2319 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS
2320 : // && !V8_TARGET_ARCH_MIPS64
2321 :
2322 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64 && \
2323 : !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2324 : void InstructionSelector::VisitI8x16Splat(Node* node) { UNIMPLEMENTED(); }
2325 :
2326 : void InstructionSelector::VisitI8x16ExtractLane(Node* node) { UNIMPLEMENTED(); }
2327 :
2328 : void InstructionSelector::VisitI8x16ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2329 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64
2330 : // && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_MIPS &&
2331 : // !V8_TARGET_ARCH_MIPS64
2332 :
2333 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2334 : !V8_TARGET_ARCH_MIPS64
2335 0 : void InstructionSelector::VisitI8x16SConvertI16x8(Node* node) {
2336 0 : UNIMPLEMENTED();
2337 : }
2338 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS
2339 : // && !V8_TARGET_ARCH_MIPS64
2340 :
2341 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64 && \
2342 : !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2343 : void InstructionSelector::VisitI8x16Add(Node* node) { UNIMPLEMENTED(); }
2344 :
2345 : void InstructionSelector::VisitI8x16AddSaturateS(Node* node) {
2346 : UNIMPLEMENTED();
2347 : }
2348 :
2349 : void InstructionSelector::VisitI8x16Sub(Node* node) { UNIMPLEMENTED(); }
2350 :
2351 : void InstructionSelector::VisitI8x16SubSaturateS(Node* node) {
2352 : UNIMPLEMENTED();
2353 : }
2354 :
2355 : void InstructionSelector::VisitI8x16MinS(Node* node) { UNIMPLEMENTED(); }
2356 :
2357 : void InstructionSelector::VisitI8x16MaxS(Node* node) { UNIMPLEMENTED(); }
2358 :
2359 : void InstructionSelector::VisitI8x16Eq(Node* node) { UNIMPLEMENTED(); }
2360 :
2361 : void InstructionSelector::VisitI8x16Ne(Node* node) { UNIMPLEMENTED(); }
2362 :
2363 : void InstructionSelector::VisitI8x16GtS(Node* node) { UNIMPLEMENTED(); }
2364 :
2365 : void InstructionSelector::VisitI8x16GeS(Node* node) { UNIMPLEMENTED(); }
2366 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64
2367 : // && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2368 :
2369 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2370 : !V8_TARGET_ARCH_MIPS64
2371 0 : void InstructionSelector::VisitI8x16Mul(Node* node) { UNIMPLEMENTED(); }
2372 :
2373 0 : void InstructionSelector::VisitI8x16ShrU(Node* node) { UNIMPLEMENTED(); }
2374 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS
2375 : // && !V8_TARGET_ARCH_MIPS64
2376 :
2377 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2378 : !V8_TARGET_ARCH_MIPS64
2379 0 : void InstructionSelector::VisitI8x16UConvertI16x8(Node* node) {
2380 0 : UNIMPLEMENTED();
2381 : }
2382 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS
2383 : // && !V8_TARGET_ARCH_MIPS64
2384 :
2385 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64 && \
2386 : !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2387 : void InstructionSelector::VisitI8x16AddSaturateU(Node* node) {
2388 : UNIMPLEMENTED();
2389 : }
2390 :
2391 : void InstructionSelector::VisitI8x16SubSaturateU(Node* node) {
2392 : UNIMPLEMENTED();
2393 : }
2394 :
2395 : void InstructionSelector::VisitI8x16MinU(Node* node) { UNIMPLEMENTED(); }
2396 :
2397 : void InstructionSelector::VisitI8x16MaxU(Node* node) { UNIMPLEMENTED(); }
2398 :
2399 : void InstructionSelector::VisitI8x16GtU(Node* node) { UNIMPLEMENTED(); }
2400 :
2401 : void InstructionSelector::VisitI8x16GeU(Node* node) { UNIMPLEMENTED(); }
2402 :
2403 : void InstructionSelector::VisitS128And(Node* node) { UNIMPLEMENTED(); }
2404 :
2405 : void InstructionSelector::VisitS128Or(Node* node) { UNIMPLEMENTED(); }
2406 :
2407 : void InstructionSelector::VisitS128Xor(Node* node) { UNIMPLEMENTED(); }
2408 :
2409 : void InstructionSelector::VisitS128Not(Node* node) { UNIMPLEMENTED(); }
2410 :
2411 : void InstructionSelector::VisitS128Zero(Node* node) { UNIMPLEMENTED(); }
2412 :
2413 : void InstructionSelector::VisitS128Select(Node* node) { UNIMPLEMENTED(); }
2414 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_X64
2415 : // && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
2416 :
2417 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2418 : !V8_TARGET_ARCH_MIPS64
2419 0 : void InstructionSelector::VisitS8x16Shuffle(Node* node) { UNIMPLEMENTED(); }
2420 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS
2421 : // && !V8_TARGET_ARCH_MIPS64
2422 :
2423 : #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2424 : !V8_TARGET_ARCH_MIPS64
2425 0 : void InstructionSelector::VisitS1x4AnyTrue(Node* node) { UNIMPLEMENTED(); }
2426 :
2427 0 : void InstructionSelector::VisitS1x4AllTrue(Node* node) { UNIMPLEMENTED(); }
2428 :
2429 0 : void InstructionSelector::VisitS1x8AnyTrue(Node* node) { UNIMPLEMENTED(); }
2430 :
2431 0 : void InstructionSelector::VisitS1x8AllTrue(Node* node) { UNIMPLEMENTED(); }
2432 :
2433 0 : void InstructionSelector::VisitS1x16AnyTrue(Node* node) { UNIMPLEMENTED(); }
2434 :
2435 0 : void InstructionSelector::VisitS1x16AllTrue(Node* node) { UNIMPLEMENTED(); }
2436 : #endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS
2437 : // && !V8_TARGET_ARCH_MIPS64
2438 :
2439 44450 : void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); }
2440 :
2441 10308162 : void InstructionSelector::VisitParameter(Node* node) {
2442 : OperandGenerator g(this);
2443 2453528 : int index = ParameterIndexOf(node->op());
2444 : InstructionOperand op =
2445 2453618 : linkage()->ParameterHasSecondaryLocation(index)
2446 : ? g.DefineAsDualLocation(
2447 : node, linkage()->GetParameterLocation(index),
2448 987886 : linkage()->GetParameterSecondaryLocation(index))
2449 4907118 : : g.DefineAsLocation(node, linkage()->GetParameterLocation(index));
2450 :
2451 2453610 : Emit(kArchNop, op);
2452 2453544 : }
2453 :
2454 : namespace {
2455 : LinkageLocation ExceptionLocation() {
2456 : return LinkageLocation::ForRegister(kReturnRegister0.code(),
2457 : MachineType::IntPtr());
2458 : }
2459 : }
2460 :
2461 138085 : void InstructionSelector::VisitIfException(Node* node) {
2462 : OperandGenerator g(this);
2463 : DCHECK_EQ(IrOpcode::kCall, node->InputAt(1)->opcode());
2464 138085 : Emit(kArchNop, g.DefineAsLocation(node, ExceptionLocation()));
2465 138085 : }
2466 :
2467 :
2468 73335 : void InstructionSelector::VisitOsrValue(Node* node) {
2469 : OperandGenerator g(this);
2470 24445 : int index = OsrValueIndexOf(node->op());
2471 : Emit(kArchNop,
2472 24445 : g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index)));
2473 24445 : }
2474 :
2475 :
2476 2853405 : void InstructionSelector::VisitPhi(Node* node) {
2477 1426699 : const int input_count = node->op()->ValueInputCount();
2478 : DCHECK_EQ(input_count, current_block_->PredecessorCount());
2479 : PhiInstruction* phi = new (instruction_zone())
2480 : PhiInstruction(instruction_zone(), GetVirtualRegister(node),
2481 2853410 : static_cast<size_t>(input_count));
2482 : sequence()
2483 : ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number()))
2484 2853412 : ->AddPhi(phi);
2485 4967651 : for (int i = 0; i < input_count; ++i) {
2486 : Node* const input = node->InputAt(i);
2487 : MarkAsUsed(input);
2488 3540953 : phi->SetInput(static_cast<size_t>(i), GetVirtualRegister(input));
2489 : }
2490 1426698 : }
2491 :
2492 :
2493 654121 : void InstructionSelector::VisitProjection(Node* node) {
2494 : OperandGenerator g(this);
2495 328333 : Node* value = node->InputAt(0);
2496 328333 : switch (value->opcode()) {
2497 : case IrOpcode::kInt32AddWithOverflow:
2498 : case IrOpcode::kInt32SubWithOverflow:
2499 : case IrOpcode::kInt32MulWithOverflow:
2500 : case IrOpcode::kInt64AddWithOverflow:
2501 : case IrOpcode::kInt64SubWithOverflow:
2502 : case IrOpcode::kTryTruncateFloat32ToInt64:
2503 : case IrOpcode::kTryTruncateFloat64ToInt64:
2504 : case IrOpcode::kTryTruncateFloat32ToUint64:
2505 : case IrOpcode::kTryTruncateFloat64ToUint64:
2506 : case IrOpcode::kInt32PairAdd:
2507 : case IrOpcode::kInt32PairSub:
2508 : case IrOpcode::kInt32PairMul:
2509 : case IrOpcode::kWord32PairShl:
2510 : case IrOpcode::kWord32PairShr:
2511 : case IrOpcode::kWord32PairSar:
2512 : case IrOpcode::kInt32AbsWithOverflow:
2513 : case IrOpcode::kInt64AbsWithOverflow:
2514 325788 : if (ProjectionIndexOf(node->op()) == 0u) {
2515 205995 : Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
2516 : } else {
2517 : DCHECK_EQ(1u, ProjectionIndexOf(node->op()));
2518 : MarkAsUsed(value);
2519 : }
2520 : break;
2521 : default:
2522 : break;
2523 : }
2524 328332 : }
2525 :
2526 :
2527 10069104 : void InstructionSelector::VisitConstant(Node* node) {
2528 : // We must emit a NOP here because every live range needs a defining
2529 : // instruction in the register allocator.
2530 : OperandGenerator g(this);
2531 10069104 : Emit(kArchNop, g.DefineAsConstant(node));
2532 10069135 : }
2533 :
2534 :
2535 22920554 : void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
2536 : OperandGenerator g(this);
2537 11943224 : const CallDescriptor* descriptor = CallDescriptorOf(node->op());
2538 :
2539 : FrameStateDescriptor* frame_state_descriptor = nullptr;
2540 4584116 : if (descriptor->NeedsFrameState()) {
2541 : frame_state_descriptor = GetFrameStateDescriptor(
2542 5467436 : node->InputAt(static_cast<int>(descriptor->InputCount())));
2543 : }
2544 :
2545 4584115 : CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
2546 :
2547 : // Compute InstructionOperands for inputs and outputs.
2548 : // TODO(turbofan): on some architectures it's probably better to use
2549 : // the code object in a register if there are multiple uses of it.
2550 : // Improve constant pool and the heuristics in the register allocator
2551 : // for where to emit constants.
2552 : CallBufferFlags call_buffer_flags(kCallCodeImmediate | kCallAddressImmediate);
2553 4584112 : InitializeCallBuffer(node, &buffer, call_buffer_flags);
2554 :
2555 4584116 : EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node);
2556 :
2557 : // Pass label of exception handler block.
2558 : CallDescriptor::Flags flags = descriptor->flags();
2559 4584105 : if (handler) {
2560 : DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode());
2561 : flags |= CallDescriptor::kHasExceptionHandler;
2562 311054 : buffer.instruction_args.push_back(g.Label(handler));
2563 : }
2564 :
2565 : bool from_native_stack = linkage()->GetIncomingDescriptor()->UseNativeStack();
2566 : bool to_native_stack = descriptor->UseNativeStack();
2567 4584105 : if (from_native_stack != to_native_stack) {
2568 : // (arm64 only) Mismatch in the use of stack pointers. One or the other
2569 : // has to be restored manually by the code generator.
2570 415427 : flags |= to_native_stack ? CallDescriptor::kRestoreJSSP
2571 : : CallDescriptor::kRestoreCSP;
2572 : }
2573 :
2574 : // Select the appropriate opcode based on the call type.
2575 : InstructionCode opcode = kArchNop;
2576 4584105 : switch (descriptor->kind()) {
2577 : case CallDescriptor::kCallAddress:
2578 : opcode =
2579 41300 : kArchCallCFunction |
2580 41300 : MiscField::encode(static_cast<int>(descriptor->ParameterCount()));
2581 41300 : break;
2582 : case CallDescriptor::kCallCodeObject:
2583 4389842 : opcode = kArchCallCodeObject | MiscField::encode(flags);
2584 4389842 : break;
2585 : case CallDescriptor::kCallJSFunction:
2586 152974 : opcode = kArchCallJSFunction | MiscField::encode(flags);
2587 152974 : break;
2588 : }
2589 :
2590 : // Emit the call instruction.
2591 4584105 : size_t const output_count = buffer.outputs.size();
2592 4584105 : auto* outputs = output_count ? &buffer.outputs.front() : nullptr;
2593 : Instruction* call_instr =
2594 : Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
2595 9168210 : &buffer.instruction_args.front());
2596 9168264 : if (instruction_selection_failed()) return;
2597 : call_instr->MarkAsCall();
2598 : }
2599 :
2600 378 : void InstructionSelector::VisitCallWithCallerSavedRegisters(
2601 378 : Node* node, BasicBlock* handler) {
2602 : OperandGenerator g(this);
2603 378 : const auto fp_mode = CallDescriptorOf(node->op())->get_save_fp_mode();
2604 378 : Emit(kArchSaveCallerRegisters | MiscField::encode(static_cast<int>(fp_mode)),
2605 378 : g.NoOutput());
2606 378 : VisitCall(node, handler);
2607 378 : Emit(kArchRestoreCallerRegisters |
2608 : MiscField::encode(static_cast<int>(fp_mode)),
2609 378 : g.NoOutput());
2610 378 : }
2611 :
2612 1305871 : void InstructionSelector::VisitTailCall(Node* node) {
2613 : OperandGenerator g(this);
2614 373106 : CallDescriptor const* descriptor = CallDescriptorOf(node->op());
2615 : DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls);
2616 :
2617 : CallDescriptor* caller = linkage()->GetIncomingDescriptor();
2618 : DCHECK(caller->CanTailCall(node));
2619 186553 : const CallDescriptor* callee = CallDescriptorOf(node->op());
2620 186553 : int stack_param_delta = callee->GetStackParameterDelta(caller);
2621 186553 : CallBuffer buffer(zone(), descriptor, nullptr);
2622 :
2623 : // Compute InstructionOperands for inputs and outputs.
2624 : CallBufferFlags flags(kCallCodeImmediate | kCallTail);
2625 186553 : if (IsTailCallAddressImmediate()) {
2626 : flags |= kCallAddressImmediate;
2627 : }
2628 186553 : InitializeCallBuffer(node, &buffer, flags, stack_param_delta);
2629 :
2630 : // Select the appropriate opcode based on the call type.
2631 : InstructionCode opcode;
2632 : InstructionOperandVector temps(zone());
2633 186553 : if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
2634 930 : switch (descriptor->kind()) {
2635 : case CallDescriptor::kCallCodeObject:
2636 : opcode = kArchTailCallCodeObjectFromJSFunction;
2637 : break;
2638 : default:
2639 0 : UNREACHABLE();
2640 : return;
2641 : }
2642 930 : int temps_count = GetTempsCountForTailCallFromJSFunction();
2643 3720 : for (int i = 0; i < temps_count; i++) {
2644 5580 : temps.push_back(g.TempRegister());
2645 : }
2646 : } else {
2647 185623 : switch (descriptor->kind()) {
2648 : case CallDescriptor::kCallCodeObject:
2649 : opcode = kArchTailCallCodeObject;
2650 : break;
2651 : case CallDescriptor::kCallAddress:
2652 : opcode = kArchTailCallAddress;
2653 30287 : break;
2654 : default:
2655 0 : UNREACHABLE();
2656 : return;
2657 : }
2658 : }
2659 186553 : opcode |= MiscField::encode(descriptor->flags());
2660 :
2661 186553 : Emit(kArchPrepareTailCall, g.NoOutput());
2662 :
2663 : int first_unused_stack_slot =
2664 : (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0) +
2665 186553 : stack_param_delta;
2666 373106 : buffer.instruction_args.push_back(g.TempImmediate(first_unused_stack_slot));
2667 :
2668 : // Emit the tailcall instruction.
2669 : Emit(opcode, 0, nullptr, buffer.instruction_args.size(),
2670 : &buffer.instruction_args.front(), temps.size(),
2671 559659 : temps.empty() ? nullptr : &temps.front());
2672 186553 : }
2673 :
2674 :
2675 6274409 : void InstructionSelector::VisitGoto(BasicBlock* target) {
2676 : // jump to the next block.
2677 : OperandGenerator g(this);
2678 6274409 : Emit(kArchJmp, g.NoOutput(), g.Label(target));
2679 6274436 : }
2680 :
2681 6996296 : void InstructionSelector::VisitReturn(Node* ret) {
2682 : OperandGenerator g(this);
2683 1510957 : const int input_count = linkage()->GetIncomingDescriptor()->ReturnCount() == 0
2684 : ? 1
2685 2742462 : : ret->op()->ValueInputCount();
2686 : DCHECK_GE(input_count, 1);
2687 1510957 : auto value_locations = zone()->NewArray<InstructionOperand>(input_count);
2688 1511009 : Node* pop_count = ret->InputAt(0);
2689 12964 : value_locations[0] = (pop_count->opcode() == IrOpcode::kInt32Constant ||
2690 : pop_count->opcode() == IrOpcode::kInt64Constant)
2691 : ? g.UseImmediate(pop_count)
2692 3009054 : : g.UseRegister(pop_count);
2693 1231991 : for (int i = 1; i < input_count; ++i) {
2694 : value_locations[i] =
2695 2463840 : g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i - 1));
2696 : }
2697 1510982 : Emit(kArchRet, 0, nullptr, input_count, value_locations);
2698 1510983 : }
2699 :
2700 0 : Instruction* InstructionSelector::EmitDeoptimize(
2701 : InstructionCode opcode, InstructionOperand output, InstructionOperand a,
2702 : DeoptimizeKind kind, DeoptimizeReason reason, Node* frame_state) {
2703 0 : size_t output_count = output.IsInvalid() ? 0 : 1;
2704 0 : InstructionOperand inputs[] = {a};
2705 : size_t input_count = arraysize(inputs);
2706 : return EmitDeoptimize(opcode, output_count, &output, input_count, inputs,
2707 0 : kind, reason, frame_state);
2708 : }
2709 :
2710 141026 : Instruction* InstructionSelector::EmitDeoptimize(
2711 : InstructionCode opcode, InstructionOperand output, InstructionOperand a,
2712 : InstructionOperand b, DeoptimizeKind kind, DeoptimizeReason reason,
2713 : Node* frame_state) {
2714 141026 : size_t output_count = output.IsInvalid() ? 0 : 1;
2715 141026 : InstructionOperand inputs[] = {a, b};
2716 : size_t input_count = arraysize(inputs);
2717 : return EmitDeoptimize(opcode, output_count, &output, input_count, inputs,
2718 141026 : kind, reason, frame_state);
2719 : }
2720 :
2721 353982 : Instruction* InstructionSelector::EmitDeoptimize(
2722 : InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
2723 : size_t input_count, InstructionOperand* inputs, DeoptimizeKind kind,
2724 353992 : DeoptimizeReason reason, Node* frame_state) {
2725 : OperandGenerator g(this);
2726 353982 : FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state);
2727 : InstructionOperandVector args(instruction_zone());
2728 353987 : args.reserve(input_count + 1 + descriptor->GetTotalSize());
2729 1037020 : for (size_t i = 0; i < input_count; ++i) {
2730 683028 : args.push_back(inputs[i]);
2731 : }
2732 353992 : opcode |= MiscField::encode(static_cast<int>(input_count));
2733 : DCHECK_NE(DeoptimizeKind::kLazy, kind);
2734 : int const state_id =
2735 353992 : sequence()->AddDeoptimizationEntry(descriptor, kind, reason);
2736 707974 : args.push_back(g.TempImmediate(state_id));
2737 : StateObjectDeduplicator deduplicator(instruction_zone());
2738 : AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator,
2739 : &args, FrameStateInputKind::kAny,
2740 353985 : instruction_zone());
2741 : return Emit(opcode, output_count, outputs, args.size(), &args.front(), 0,
2742 707984 : nullptr);
2743 : }
2744 :
2745 268799 : void InstructionSelector::EmitIdentity(Node* node) {
2746 : OperandGenerator g(this);
2747 : MarkAsUsed(node->InputAt(0));
2748 268799 : SetRename(node, node->InputAt(0));
2749 268829 : }
2750 :
2751 0 : void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind,
2752 : DeoptimizeReason reason,
2753 : Node* value) {
2754 51672 : EmitDeoptimize(kArchDeoptimize, 0, nullptr, 0, nullptr, kind, reason, value);
2755 0 : }
2756 :
2757 0 : void InstructionSelector::VisitThrow(Node* node) {
2758 : OperandGenerator g(this);
2759 81952 : Emit(kArchThrowTerminator, g.NoOutput());
2760 0 : }
2761 :
2762 0 : void InstructionSelector::VisitDebugBreak(Node* node) {
2763 : OperandGenerator g(this);
2764 22395 : Emit(kArchDebugBreak, g.NoOutput());
2765 0 : }
2766 :
2767 0 : void InstructionSelector::VisitComment(Node* node) {
2768 : OperandGenerator g(this);
2769 0 : InstructionOperand operand(g.UseImmediate(node));
2770 0 : Emit(kArchComment, 0, nullptr, 1, &operand);
2771 0 : }
2772 :
2773 0 : void InstructionSelector::VisitUnsafePointerAdd(Node* node) {
2774 : #if V8_TARGET_ARCH_64_BIT
2775 6575 : VisitInt64Add(node);
2776 : #else // V8_TARGET_ARCH_64_BIT
2777 : VisitInt32Add(node);
2778 : #endif // V8_TARGET_ARCH_64_BIT
2779 0 : }
2780 :
2781 12192 : void InstructionSelector::VisitRetain(Node* node) {
2782 : OperandGenerator g(this);
2783 12192 : Emit(kArchNop, g.NoOutput(), g.UseAny(node->InputAt(0)));
2784 12192 : }
2785 :
2786 2063 : bool InstructionSelector::CanProduceSignalingNaN(Node* node) {
2787 : // TODO(jarin) Improve the heuristic here.
2788 3925 : if (node->opcode() == IrOpcode::kFloat64Add ||
2789 3916 : node->opcode() == IrOpcode::kFloat64Sub ||
2790 : node->opcode() == IrOpcode::kFloat64Mul) {
2791 : return false;
2792 : }
2793 0 : return true;
2794 : }
2795 :
2796 3360380 : FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
2797 : Node* state) {
2798 : DCHECK_EQ(IrOpcode::kFrameState, state->opcode());
2799 : DCHECK_EQ(kFrameStateInputCount, state->InputCount());
2800 3360380 : FrameStateInfo state_info = OpParameter<FrameStateInfo>(state);
2801 :
2802 : int parameters = static_cast<int>(
2803 3360380 : StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size());
2804 : int locals = static_cast<int>(
2805 3360394 : StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size());
2806 : int stack = static_cast<int>(
2807 3360394 : StateValuesAccess(state->InputAt(kFrameStateStackInput)).size());
2808 :
2809 : DCHECK_EQ(parameters, state_info.parameter_count());
2810 : DCHECK_EQ(locals, state_info.local_count());
2811 :
2812 : FrameStateDescriptor* outer_state = nullptr;
2813 3360394 : Node* outer_node = state->InputAt(kFrameStateOuterStateInput);
2814 3360394 : if (outer_node->opcode() == IrOpcode::kFrameState) {
2815 272677 : outer_state = GetFrameStateDescriptor(outer_node);
2816 : }
2817 :
2818 : return new (instruction_zone()) FrameStateDescriptor(
2819 : instruction_zone(), state_info.type(), state_info.bailout_id(),
2820 : state_info.state_combine(), parameters, locals, stack,
2821 10081168 : state_info.shared_info(), outer_state);
2822 : }
2823 :
2824 : // static
2825 0 : bool InstructionSelector::TryMatch32x4Shuffle(const uint8_t* shuffle,
2826 : uint8_t* shuffle32x4) {
2827 0 : for (int i = 0; i < 4; ++i) {
2828 0 : if (shuffle[i * 4] % 4 != 0) return false;
2829 0 : for (int j = 1; j < 4; ++j) {
2830 0 : if (shuffle[i * 4 + j] - shuffle[i * 4 + j - 1] != 1) return false;
2831 : }
2832 0 : shuffle32x4[i] = shuffle[i * 4] / 4;
2833 : }
2834 : return true;
2835 : }
2836 :
2837 : // static
2838 0 : bool InstructionSelector::TryMatchConcat(const uint8_t* shuffle, uint8_t mask,
2839 : uint8_t* vext) {
2840 0 : uint8_t start = shuffle[0];
2841 : int i = 1;
2842 0 : for (; i < 16 - start; ++i) {
2843 0 : if ((shuffle[i] & mask) != ((shuffle[i - 1] + 1) & mask)) return false;
2844 : }
2845 : uint8_t wrap = 16;
2846 0 : for (; i < 16; ++i, ++wrap) {
2847 0 : if ((shuffle[i] & mask) != (wrap & mask)) return false;
2848 : }
2849 0 : *vext = start;
2850 0 : return true;
2851 : }
2852 :
2853 : // Canonicalize shuffles to make pattern matching simpler. Returns a mask that
2854 : // will ignore the high bit of indices in some cases.
2855 0 : uint8_t InstructionSelector::CanonicalizeShuffle(Node* node) {
2856 : static const int kMaxLaneIndex = 15;
2857 : static const int kMaxShuffleIndex = 31;
2858 :
2859 0 : const uint8_t* shuffle = OpParameter<uint8_t*>(node);
2860 : uint8_t mask = kMaxShuffleIndex;
2861 : // If shuffle is unary, set 'mask' to ignore the high bit of the indices.
2862 : // Replace any unused source with the other.
2863 0 : if (GetVirtualRegister(node->InputAt(0)) ==
2864 0 : GetVirtualRegister(node->InputAt(1))) {
2865 : // unary, src0 == src1.
2866 : mask = kMaxLaneIndex;
2867 : } else {
2868 : bool src0_is_used = false;
2869 : bool src1_is_used = false;
2870 0 : for (int i = 0; i < 16; ++i) {
2871 0 : if (shuffle[i] < 16) {
2872 : src0_is_used = true;
2873 : } else {
2874 : src1_is_used = true;
2875 : }
2876 : }
2877 0 : if (src0_is_used && !src1_is_used) {
2878 0 : node->ReplaceInput(1, node->InputAt(0));
2879 : mask = kMaxLaneIndex;
2880 0 : } else if (src1_is_used && !src0_is_used) {
2881 0 : node->ReplaceInput(0, node->InputAt(1));
2882 : mask = kMaxLaneIndex;
2883 : }
2884 : }
2885 0 : return mask;
2886 : }
2887 :
2888 : // static
2889 0 : int32_t InstructionSelector::Pack4Lanes(const uint8_t* shuffle, uint8_t mask) {
2890 : int32_t result = 0;
2891 0 : for (int i = 3; i >= 0; --i) {
2892 0 : result <<= 8;
2893 0 : result |= shuffle[i] & mask;
2894 : }
2895 0 : return result;
2896 : }
2897 :
2898 : } // namespace compiler
2899 : } // namespace internal
2900 : } // namespace v8
|