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/base/adapters.h" 10 #include "src/compiler/compiler-source-position-table.h" 11 #include "src/compiler/instruction-selector-impl.h" 12 #include "src/compiler/node-matchers.h" 13 #include "src/compiler/pipeline.h" 14 #include "src/compiler/schedule.h" 15 #include "src/compiler/state-values-utils.h" 16 #include "src/deoptimizer.h" 17 #include "src/objects-inl.h" 18 19 namespace v8 { 20 namespace internal { 21 namespace compiler { 22 23 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 instruction_selection_failed_(false) { 50 instructions_.reserve(node_count); 51 } 52 53 bool InstructionSelector::SelectInstructions() { 54 // Mark the inputs of all phis in loop headers as used. 55 BasicBlockVector* blocks = schedule()->rpo_order(); 56 for (auto const block : *blocks) { 57 if (!block->IsLoopHeader()) continue; 58 DCHECK_LE(2u, block->PredecessorCount()); 59 for (Node* const phi : *block) { 60 if (phi->opcode() != IrOpcode::kPhi) continue; 61 62 // Mark all inputs as used. 63 for (Node* const input : phi->inputs()) { 64 MarkAsUsed(input); 65 } 66 } 67 } 68 69 // Visit each basic block in post order. 70 for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) { 71 VisitBlock(*i); 72 if (instruction_selection_failed()) return false; 73 } 74 75 // Schedule the selected instructions. 76 if (UseInstructionScheduling()) { 77 scheduler_ = new (zone()) InstructionScheduler(zone(), sequence()); 78 } 79 80 for (auto const block : *blocks) { 81 InstructionBlock* instruction_block = 82 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); 83 for (size_t i = 0; i < instruction_block->phis().size(); i++) { 84 UpdateRenamesInPhi(instruction_block->PhiAt(i)); 85 } 86 size_t end = instruction_block->code_end(); 87 size_t start = instruction_block->code_start(); 88 DCHECK_LE(end, start); 89 StartBlock(RpoNumber::FromInt(block->rpo_number())); 90 while (start-- > end) { 91 UpdateRenames(instructions_[start]); 92 AddInstruction(instructions_[start]); 93 } 94 EndBlock(RpoNumber::FromInt(block->rpo_number())); 95 } 96 #if DEBUG 97 sequence()->ValidateSSA(); 98 #endif 99 return true; 100 } 101 102 void InstructionSelector::StartBlock(RpoNumber rpo) { 103 if (UseInstructionScheduling()) { 104 DCHECK_NOT_NULL(scheduler_); 105 scheduler_->StartBlock(rpo); 106 } else { 107 sequence()->StartBlock(rpo); 108 } 109 } 110 111 112 void InstructionSelector::EndBlock(RpoNumber rpo) { 113 if (UseInstructionScheduling()) { 114 DCHECK_NOT_NULL(scheduler_); 115 scheduler_->EndBlock(rpo); 116 } else { 117 sequence()->EndBlock(rpo); 118 } 119 } 120 121 122 void InstructionSelector::AddInstruction(Instruction* instr) { 123 if (UseInstructionScheduling()) { 124 DCHECK_NOT_NULL(scheduler_); 125 scheduler_->AddInstruction(instr); 126 } else { 127 sequence()->AddInstruction(instr); 128 } 129 } 130 131 Instruction* InstructionSelector::Emit(InstructionCode opcode, 132 InstructionOperand output, 133 size_t temp_count, 134 InstructionOperand* temps) { 135 size_t output_count = output.IsInvalid() ? 0 : 1; 136 return Emit(opcode, output_count, &output, 0, nullptr, temp_count, temps); 137 } 138 139 140 Instruction* InstructionSelector::Emit(InstructionCode opcode, 141 InstructionOperand output, 142 InstructionOperand a, size_t temp_count, 143 InstructionOperand* temps) { 144 size_t output_count = output.IsInvalid() ? 0 : 1; 145 return Emit(opcode, output_count, &output, 1, &a, temp_count, temps); 146 } 147 148 149 Instruction* InstructionSelector::Emit(InstructionCode opcode, 150 InstructionOperand output, 151 InstructionOperand a, 152 InstructionOperand b, size_t temp_count, 153 InstructionOperand* temps) { 154 size_t output_count = output.IsInvalid() ? 0 : 1; 155 InstructionOperand inputs[] = {a, b}; 156 size_t input_count = arraysize(inputs); 157 return Emit(opcode, output_count, &output, input_count, inputs, temp_count, 158 temps); 159 } 160 161 162 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 size_t output_count = output.IsInvalid() ? 0 : 1; 169 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 temps); 173 } 174 175 176 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 size_t output_count = output.IsInvalid() ? 0 : 1; 181 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 temps); 185 } 186 187 188 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 size_t output_count = output.IsInvalid() ? 0 : 1; 193 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 temps); 197 } 198 199 200 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 size_t output_count = output.IsInvalid() ? 0 : 1; 206 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 temps); 210 } 211 212 213 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 if (output_count >= Instruction::kMaxOutputCount || 218 input_count >= Instruction::kMaxInputCount || 219 temp_count >= Instruction::kMaxTempCount) { 220 set_instruction_selection_failed(); 221 return nullptr; 222 } 223 224 Instruction* instr = 225 Instruction::New(instruction_zone(), opcode, output_count, outputs, 226 input_count, inputs, temp_count, temps); 227 return Emit(instr); 228 } 229 230 231 Instruction* InstructionSelector::Emit(Instruction* instr) { 232 instructions_.push_back(instr); 233 return instr; 234 } 235 236 237 bool InstructionSelector::CanCover(Node* user, Node* node) const { 238 // 1. Both {user} and {node} must be in the same basic block. 239 if (schedule()->block(node) != schedule()->block(user)) { 240 return false; 241 } 242 // 2. Pure {node}s must be owned by the {user}. 243 if (node->op()->HasProperty(Operator::kPure)) { 244 return node->OwnedBy(user); 245 } 246 // 3. Impure {node}s must match the effect level of {user}. 247 if (GetEffectLevel(node) != GetEffectLevel(user)) { 248 return false; 249 } 250 // 4. Only {node} must have value edges pointing to {user}. 251 for (Edge const edge : node->use_edges()) { 252 if (edge.from() != user && NodeProperties::IsValueEdge(edge)) { 253 return false; 254 } 255 } 256 return true; 257 } 258 259 bool InstructionSelector::IsOnlyUserOfNodeInSameBlock(Node* user, 260 Node* node) const { 261 BasicBlock* bb_user = schedule()->block(user); 262 BasicBlock* bb_node = schedule()->block(node); 263 if (bb_user != bb_node) return false; 264 for (Edge const edge : node->use_edges()) { 265 Node* from = edge.from(); 266 if ((from != user) && (schedule()->block(from) == bb_user)) { 267 return false; 268 } 269 } 270 return true; 271 } 272 273 void InstructionSelector::UpdateRenames(Instruction* instruction) { 274 for (size_t i = 0; i < instruction->InputCount(); i++) { 275 TryRename(instruction->InputAt(i)); 276 } 277 } 278 279 void InstructionSelector::UpdateRenamesInPhi(PhiInstruction* phi) { 280 for (size_t i = 0; i < phi->operands().size(); i++) { 281 int vreg = phi->operands()[i]; 282 int renamed = GetRename(vreg); 283 if (vreg != renamed) { 284 phi->RenameInput(i, renamed); 285 } 286 } 287 } 288 289 int InstructionSelector::GetRename(int virtual_register) { 290 int rename = virtual_register; 291 while (true) { 292 if (static_cast<size_t>(rename) >= virtual_register_rename_.size()) break; 293 int next = virtual_register_rename_[rename]; 294 if (next == InstructionOperand::kInvalidVirtualRegister) { 295 break; 296 } 297 rename = next; 298 } 299 return rename; 300 } 301 302 void InstructionSelector::TryRename(InstructionOperand* op) { 303 if (!op->IsUnallocated()) return; 304 int vreg = UnallocatedOperand::cast(op)->virtual_register(); 305 int rename = GetRename(vreg); 306 if (rename != vreg) { 307 UnallocatedOperand::cast(op)->set_virtual_register(rename); 308 } 309 } 310 311 void InstructionSelector::SetRename(const Node* node, const Node* rename) { 312 int vreg = GetVirtualRegister(node); 313 if (static_cast<size_t>(vreg) >= virtual_register_rename_.size()) { 314 int invalid = InstructionOperand::kInvalidVirtualRegister; 315 virtual_register_rename_.resize(vreg + 1, invalid); 316 } 317 virtual_register_rename_[vreg] = GetVirtualRegister(rename); 318 } 319 320 int InstructionSelector::GetVirtualRegister(const Node* node) { 321 DCHECK_NOT_NULL(node); 322 size_t const id = node->id(); 323 DCHECK_LT(id, virtual_registers_.size()); 324 int virtual_register = virtual_registers_[id]; 325 if (virtual_register == InstructionOperand::kInvalidVirtualRegister) { 326 virtual_register = sequence()->NextVirtualRegister(); 327 virtual_registers_[id] = virtual_register; 328 } 329 return virtual_register; 330 } 331 332 333 const std::map<NodeId, int> InstructionSelector::GetVirtualRegistersForTesting() 334 const { 335 std::map<NodeId, int> virtual_registers; 336 for (size_t n = 0; n < virtual_registers_.size(); ++n) { 337 if (virtual_registers_[n] != InstructionOperand::kInvalidVirtualRegister) { 338 NodeId const id = static_cast<NodeId>(n); 339 virtual_registers.insert(std::make_pair(id, virtual_registers_[n])); 340 } 341 } 342 return virtual_registers; 343 } 344 345 346 bool InstructionSelector::IsDefined(Node* node) const { 347 DCHECK_NOT_NULL(node); 348 size_t const id = node->id(); 349 DCHECK_LT(id, defined_.size()); 350 return defined_[id]; 351 } 352 353 354 void InstructionSelector::MarkAsDefined(Node* node) { 355 DCHECK_NOT_NULL(node); 356 size_t const id = node->id(); 357 DCHECK_LT(id, defined_.size()); 358 defined_[id] = true; 359 } 360 361 362 bool InstructionSelector::IsUsed(Node* node) const { 363 DCHECK_NOT_NULL(node); 364 // TODO(bmeurer): This is a terrible monster hack, but we have to make sure 365 // that the Retain is actually emitted, otherwise the GC will mess up. 366 if (node->opcode() == IrOpcode::kRetain) return true; 367 if (!node->op()->HasProperty(Operator::kEliminatable)) return true; 368 size_t const id = node->id(); 369 DCHECK_LT(id, used_.size()); 370 return used_[id]; 371 } 372 373 374 void InstructionSelector::MarkAsUsed(Node* node) { 375 DCHECK_NOT_NULL(node); 376 size_t const id = node->id(); 377 DCHECK_LT(id, used_.size()); 378 used_[id] = true; 379 } 380 381 int InstructionSelector::GetEffectLevel(Node* node) const { 382 DCHECK_NOT_NULL(node); 383 size_t const id = node->id(); 384 DCHECK_LT(id, effect_level_.size()); 385 return effect_level_[id]; 386 } 387 388 void InstructionSelector::SetEffectLevel(Node* node, int effect_level) { 389 DCHECK_NOT_NULL(node); 390 size_t const id = node->id(); 391 DCHECK_LT(id, effect_level_.size()); 392 effect_level_[id] = effect_level; 393 } 394 395 bool InstructionSelector::CanAddressRelativeToRootsRegister() const { 396 return enable_serialization_ == kDisableSerialization && 397 CanUseRootsRegister(); 398 } 399 400 bool InstructionSelector::CanUseRootsRegister() const { 401 return linkage()->GetIncomingDescriptor()->flags() & 402 CallDescriptor::kCanUseRoots; 403 } 404 405 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, 406 const InstructionOperand& op) { 407 UnallocatedOperand unalloc = UnallocatedOperand::cast(op); 408 sequence()->MarkAsRepresentation(rep, unalloc.virtual_register()); 409 } 410 411 412 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, 413 Node* node) { 414 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node)); 415 } 416 417 namespace { 418 419 InstructionOperand OperandForDeopt(Isolate* isolate, OperandGenerator* g, 420 Node* input, FrameStateInputKind kind, 421 MachineRepresentation rep) { 422 if (rep == MachineRepresentation::kNone) { 423 return g->TempImmediate(FrameStateDescriptor::kImpossibleValue); 424 } 425 426 switch (input->opcode()) { 427 case IrOpcode::kInt32Constant: 428 case IrOpcode::kInt64Constant: 429 case IrOpcode::kNumberConstant: 430 case IrOpcode::kFloat32Constant: 431 case IrOpcode::kFloat64Constant: 432 return g->UseImmediate(input); 433 case IrOpcode::kHeapConstant: { 434 if (!CanBeTaggedPointer(rep)) { 435 // If we have inconsistent static and dynamic types, e.g. if we 436 // smi-check a string, we can get here with a heap object that 437 // says it is a smi. In that case, we return an invalid instruction 438 // operand, which will be interpreted as an optimized-out value. 439 440 // TODO(jarin) Ideally, we should turn the current instruction 441 // into an abort (we should never execute it). 442 return InstructionOperand(); 443 } 444 445 Handle<HeapObject> constant = OpParameter<Handle<HeapObject>>(input); 446 Heap::RootListIndex root_index; 447 if (isolate->heap()->IsRootHandle(constant, &root_index) && 448 root_index == Heap::kOptimizedOutRootIndex) { 449 // For an optimized-out object we return an invalid instruction 450 // operand, so that we take the fast path for optimized-out values. 451 return InstructionOperand(); 452 } 453 454 return g->UseImmediate(input); 455 } 456 case IrOpcode::kArgumentsObjectState: 457 case IrOpcode::kObjectState: 458 case IrOpcode::kTypedObjectState: 459 UNREACHABLE(); 460 break; 461 default: 462 switch (kind) { 463 case FrameStateInputKind::kStackSlot: 464 return g->UseUniqueSlot(input); 465 case FrameStateInputKind::kAny: 466 // Currently deopts "wrap" other operations, so the deopt's inputs 467 // are potentially needed untill the end of the deoptimising code. 468 return g->UseAnyAtEnd(input); 469 } 470 } 471 UNREACHABLE(); 472 return InstructionOperand(); 473 } 474 475 } // namespace 476 477 class StateObjectDeduplicator { 478 public: 479 explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {} 480 static const size_t kNotDuplicated = SIZE_MAX; 481 482 size_t GetObjectId(Node* node) { 483 for (size_t i = 0; i < objects_.size(); ++i) { 484 if (objects_[i] == node) { 485 return i; 486 } 487 } 488 return kNotDuplicated; 489 } 490 491 size_t InsertObject(Node* node) { 492 size_t id = objects_.size(); 493 objects_.push_back(node); 494 return id; 495 } 496 497 private: 498 ZoneVector<Node*> objects_; 499 }; 500 501 // Returns the number of instruction operands added to inputs. 502 size_t InstructionSelector::AddOperandToStateValueDescriptor( 503 StateValueList* values, InstructionOperandVector* inputs, 504 OperandGenerator* g, StateObjectDeduplicator* deduplicator, Node* input, 505 MachineType type, FrameStateInputKind kind, Zone* zone) { 506 if (input == nullptr) { 507 values->PushOptimizedOut(); 508 return 0; 509 } 510 511 switch (input->opcode()) { 512 case IrOpcode::kArgumentsObjectState: { 513 values->PushArguments(); 514 return 0; 515 } 516 case IrOpcode::kObjectState: { 517 UNREACHABLE(); 518 return 0; 519 } 520 case IrOpcode::kTypedObjectState: { 521 size_t id = deduplicator->GetObjectId(input); 522 if (id == StateObjectDeduplicator::kNotDuplicated) { 523 size_t entries = 0; 524 id = deduplicator->InsertObject(input); 525 StateValueList* nested = values->PushRecursiveField(zone, id); 526 int const input_count = input->op()->ValueInputCount(); 527 ZoneVector<MachineType> const* types = MachineTypesOf(input->op()); 528 for (int i = 0; i < input_count; ++i) { 529 entries += AddOperandToStateValueDescriptor( 530 nested, inputs, g, deduplicator, input->InputAt(i), types->at(i), 531 kind, zone); 532 } 533 return entries; 534 } else { 535 // Crankshaft counts duplicate objects for the running id, so we have 536 // to push the input again. 537 deduplicator->InsertObject(input); 538 values->PushDuplicate(id); 539 return 0; 540 } 541 } 542 default: { 543 InstructionOperand op = 544 OperandForDeopt(isolate(), g, input, kind, type.representation()); 545 if (op.kind() == InstructionOperand::INVALID) { 546 // Invalid operand means the value is impossible or optimized-out. 547 values->PushOptimizedOut(); 548 return 0; 549 } else { 550 inputs->push_back(op); 551 values->PushPlain(type); 552 return 1; 553 } 554 } 555 } 556 } 557 558 559 // Returns the number of instruction operands added to inputs. 560 size_t InstructionSelector::AddInputsToFrameStateDescriptor( 561 FrameStateDescriptor* descriptor, Node* state, OperandGenerator* g, 562 StateObjectDeduplicator* deduplicator, InstructionOperandVector* inputs, 563 FrameStateInputKind kind, Zone* zone) { 564 DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode()); 565 566 size_t entries = 0; 567 size_t initial_size = inputs->size(); 568 USE(initial_size); // initial_size is only used for debug. 569 570 if (descriptor->outer_state()) { 571 entries += AddInputsToFrameStateDescriptor( 572 descriptor->outer_state(), state->InputAt(kFrameStateOuterStateInput), 573 g, deduplicator, inputs, kind, zone); 574 } 575 576 Node* parameters = state->InputAt(kFrameStateParametersInput); 577 Node* locals = state->InputAt(kFrameStateLocalsInput); 578 Node* stack = state->InputAt(kFrameStateStackInput); 579 Node* context = state->InputAt(kFrameStateContextInput); 580 Node* function = state->InputAt(kFrameStateFunctionInput); 581 582 DCHECK_EQ(descriptor->parameters_count(), 583 StateValuesAccess(parameters).size()); 584 DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size()); 585 DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size()); 586 587 StateValueList* values_descriptor = descriptor->GetStateValueDescriptors(); 588 589 DCHECK_EQ(values_descriptor->size(), 0u); 590 values_descriptor->ReserveSize( 591 descriptor->GetSize(OutputFrameStateCombine::Ignore())); 592 593 entries += AddOperandToStateValueDescriptor( 594 values_descriptor, inputs, g, deduplicator, function, 595 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone); 596 for (StateValuesAccess::TypedNode input_node : 597 StateValuesAccess(parameters)) { 598 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g, 599 deduplicator, input_node.node, 600 input_node.type, kind, zone); 601 } 602 if (descriptor->HasContext()) { 603 entries += AddOperandToStateValueDescriptor( 604 values_descriptor, inputs, g, deduplicator, context, 605 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone); 606 } 607 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) { 608 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g, 609 deduplicator, input_node.node, 610 input_node.type, kind, zone); 611 } 612 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) { 613 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g, 614 deduplicator, input_node.node, 615 input_node.type, kind, zone); 616 } 617 DCHECK_EQ(initial_size + entries, inputs->size()); 618 return entries; 619 } 620 621 622 // An internal helper class for generating the operands to calls. 623 // TODO(bmeurer): Get rid of the CallBuffer business and make 624 // InstructionSelector::VisitCall platform independent instead. 625 struct CallBuffer { 626 CallBuffer(Zone* zone, const CallDescriptor* descriptor, 627 FrameStateDescriptor* frame_state) 628 : descriptor(descriptor), 629 frame_state_descriptor(frame_state), 630 output_nodes(zone), 631 outputs(zone), 632 instruction_args(zone), 633 pushed_nodes(zone) { 634 output_nodes.reserve(descriptor->ReturnCount()); 635 outputs.reserve(descriptor->ReturnCount()); 636 pushed_nodes.reserve(input_count()); 637 instruction_args.reserve(input_count() + frame_state_value_count()); 638 } 639 640 641 const CallDescriptor* descriptor; 642 FrameStateDescriptor* frame_state_descriptor; 643 NodeVector output_nodes; 644 InstructionOperandVector outputs; 645 InstructionOperandVector instruction_args; 646 ZoneVector<PushParameter> pushed_nodes; 647 648 size_t input_count() const { return descriptor->InputCount(); } 649 650 size_t frame_state_count() const { return descriptor->FrameStateCount(); } 651 652 size_t frame_state_value_count() const { 653 return (frame_state_descriptor == nullptr) 654 ? 0 655 : (frame_state_descriptor->GetTotalSize() + 656 1); // Include deopt id. 657 } 658 }; 659 660 661 // TODO(bmeurer): Get rid of the CallBuffer business and make 662 // InstructionSelector::VisitCall platform independent instead. 663 void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, 664 CallBufferFlags flags, 665 int stack_param_delta) { 666 OperandGenerator g(this); 667 DCHECK_LE(call->op()->ValueOutputCount(), 668 static_cast<int>(buffer->descriptor->ReturnCount())); 669 DCHECK_EQ( 670 call->op()->ValueInputCount(), 671 static_cast<int>(buffer->input_count() + buffer->frame_state_count())); 672 673 if (buffer->descriptor->ReturnCount() > 0) { 674 // Collect the projections that represent multiple outputs from this call. 675 if (buffer->descriptor->ReturnCount() == 1) { 676 buffer->output_nodes.push_back(call); 677 } else { 678 buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), nullptr); 679 for (auto use : call->uses()) { 680 if (use->opcode() != IrOpcode::kProjection) continue; 681 size_t const index = ProjectionIndexOf(use->op()); 682 DCHECK_LT(index, buffer->output_nodes.size()); 683 DCHECK(!buffer->output_nodes[index]); 684 buffer->output_nodes[index] = use; 685 } 686 } 687 688 // Filter out the outputs that aren't live because no projection uses them. 689 size_t outputs_needed_by_framestate = 690 buffer->frame_state_descriptor == nullptr 691 ? 0 692 : buffer->frame_state_descriptor->state_combine() 693 .ConsumedOutputCount(); 694 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { 695 bool output_is_live = buffer->output_nodes[i] != nullptr || 696 i < outputs_needed_by_framestate; 697 if (output_is_live) { 698 MachineRepresentation rep = 699 buffer->descriptor->GetReturnType(static_cast<int>(i)) 700 .representation(); 701 LinkageLocation location = 702 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); 703 704 Node* output = buffer->output_nodes[i]; 705 InstructionOperand op = output == nullptr 706 ? g.TempLocation(location) 707 : g.DefineAsLocation(output, location); 708 MarkAsRepresentation(rep, op); 709 710 buffer->outputs.push_back(op); 711 } 712 } 713 } 714 715 // The first argument is always the callee code. 716 Node* callee = call->InputAt(0); 717 bool call_code_immediate = (flags & kCallCodeImmediate) != 0; 718 bool call_address_immediate = (flags & kCallAddressImmediate) != 0; 719 switch (buffer->descriptor->kind()) { 720 case CallDescriptor::kCallCodeObject: 721 buffer->instruction_args.push_back( 722 (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant) 723 ? g.UseImmediate(callee) 724 : g.UseRegister(callee)); 725 break; 726 case CallDescriptor::kCallAddress: 727 buffer->instruction_args.push_back( 728 (call_address_immediate && 729 callee->opcode() == IrOpcode::kExternalConstant) 730 ? g.UseImmediate(callee) 731 : g.UseRegister(callee)); 732 break; 733 case CallDescriptor::kCallJSFunction: 734 buffer->instruction_args.push_back( 735 g.UseLocation(callee, buffer->descriptor->GetInputLocation(0))); 736 break; 737 } 738 DCHECK_EQ(1u, buffer->instruction_args.size()); 739 740 // If the call needs a frame state, we insert the state information as 741 // follows (n is the number of value inputs to the frame state): 742 // arg 1 : deoptimization id. 743 // arg 2 - arg (n + 1) : value inputs to the frame state. 744 size_t frame_state_entries = 0; 745 USE(frame_state_entries); // frame_state_entries is only used for debug. 746 if (buffer->frame_state_descriptor != nullptr) { 747 Node* frame_state = 748 call->InputAt(static_cast<int>(buffer->descriptor->InputCount())); 749 750 // If it was a syntactic tail call we need to drop the current frame and 751 // all the frames on top of it that are either an arguments adaptor frame 752 // or a tail caller frame. 753 if (buffer->descriptor->SupportsTailCalls()) { 754 frame_state = NodeProperties::GetFrameStateInput(frame_state); 755 buffer->frame_state_descriptor = 756 buffer->frame_state_descriptor->outer_state(); 757 while (buffer->frame_state_descriptor != nullptr && 758 (buffer->frame_state_descriptor->type() == 759 FrameStateType::kArgumentsAdaptor || 760 buffer->frame_state_descriptor->type() == 761 FrameStateType::kTailCallerFunction)) { 762 frame_state = NodeProperties::GetFrameStateInput(frame_state); 763 buffer->frame_state_descriptor = 764 buffer->frame_state_descriptor->outer_state(); 765 } 766 } 767 768 int const state_id = sequence()->AddDeoptimizationEntry( 769 buffer->frame_state_descriptor, DeoptimizeKind::kEager, 770 DeoptimizeReason::kNoReason); 771 buffer->instruction_args.push_back(g.TempImmediate(state_id)); 772 773 StateObjectDeduplicator deduplicator(instruction_zone()); 774 775 frame_state_entries = 776 1 + AddInputsToFrameStateDescriptor( 777 buffer->frame_state_descriptor, frame_state, &g, &deduplicator, 778 &buffer->instruction_args, FrameStateInputKind::kStackSlot, 779 instruction_zone()); 780 781 DCHECK_EQ(1 + frame_state_entries, buffer->instruction_args.size()); 782 } 783 784 size_t input_count = static_cast<size_t>(buffer->input_count()); 785 786 // Split the arguments into pushed_nodes and instruction_args. Pushed 787 // arguments require an explicit push instruction before the call and do 788 // not appear as arguments to the call. Everything else ends up 789 // as an InstructionOperand argument to the call. 790 auto iter(call->inputs().begin()); 791 size_t pushed_count = 0; 792 bool call_tail = (flags & kCallTail) != 0; 793 for (size_t index = 0; index < input_count; ++iter, ++index) { 794 DCHECK(iter != call->inputs().end()); 795 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); 796 if (index == 0) continue; // The first argument (callee) is already done. 797 798 LinkageLocation location = buffer->descriptor->GetInputLocation(index); 799 if (call_tail) { 800 location = LinkageLocation::ConvertToTailCallerLocation( 801 location, stack_param_delta); 802 } 803 InstructionOperand op = g.UseLocation(*iter, location); 804 if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) { 805 int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1; 806 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { 807 buffer->pushed_nodes.resize(stack_index + 1); 808 } 809 PushParameter parameter(*iter, buffer->descriptor->GetInputType(index)); 810 buffer->pushed_nodes[stack_index] = parameter; 811 pushed_count++; 812 } else { 813 buffer->instruction_args.push_back(op); 814 } 815 } 816 DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count - 817 frame_state_entries); 818 if (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK && call_tail && 819 stack_param_delta != 0) { 820 // For tail calls that change the size of their parameter list and keep 821 // their return address on the stack, move the return address to just above 822 // the parameters. 823 LinkageLocation saved_return_location = 824 LinkageLocation::ForSavedCallerReturnAddress(); 825 InstructionOperand return_address = 826 g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation( 827 saved_return_location, stack_param_delta), 828 saved_return_location); 829 buffer->instruction_args.push_back(return_address); 830 } 831 } 832 833 bool InstructionSelector::IsSourcePositionUsed(Node* node) { 834 return (source_position_mode_ == kAllSourcePositions || 835 node->opcode() == IrOpcode::kCall || 836 node->opcode() == IrOpcode::kTrapIf || 837 node->opcode() == IrOpcode::kTrapUnless); 838 } 839 840 void InstructionSelector::VisitBlock(BasicBlock* block) { 841 DCHECK(!current_block_); 842 current_block_ = block; 843 auto current_num_instructions = [&] { 844 DCHECK_GE(kMaxInt, instructions_.size()); 845 return static_cast<int>(instructions_.size()); 846 }; 847 int current_block_end = current_num_instructions(); 848 849 int effect_level = 0; 850 for (Node* const node : *block) { 851 SetEffectLevel(node, effect_level); 852 if (node->opcode() == IrOpcode::kStore || 853 node->opcode() == IrOpcode::kUnalignedStore || 854 node->opcode() == IrOpcode::kCheckedStore || 855 node->opcode() == IrOpcode::kCall || 856 node->opcode() == IrOpcode::kProtectedLoad || 857 node->opcode() == IrOpcode::kProtectedStore) { 858 ++effect_level; 859 } 860 } 861 862 // We visit the control first, then the nodes in the block, so the block's 863 // control input should be on the same effect level as the last node. 864 if (block->control_input() != nullptr) { 865 SetEffectLevel(block->control_input(), effect_level); 866 } 867 868 auto FinishEmittedInstructions = [&](Node* node, int instruction_start) { 869 if (instruction_selection_failed()) return false; 870 if (current_num_instructions() == instruction_start) return true; 871 std::reverse(instructions_.begin() + instruction_start, 872 instructions_.end()); 873 if (!node) return true; 874 SourcePosition source_position = source_positions_->GetSourcePosition(node); 875 if (source_position.IsKnown() && IsSourcePositionUsed(node)) { 876 sequence()->SetSourcePosition(instructions_[instruction_start], 877 source_position); 878 } 879 return true; 880 }; 881 882 // Generate code for the block control "top down", but schedule the code 883 // "bottom up". 884 VisitControl(block); 885 if (!FinishEmittedInstructions(block->control_input(), current_block_end)) 886 return; 887 888 // Visit code in reverse control flow order, because architecture-specific 889 // matching may cover more than one node at a time. 890 for (auto node : base::Reversed(*block)) { 891 // Skip nodes that are unused or already defined. 892 if (!IsUsed(node) || IsDefined(node)) continue; 893 // Generate code for this node "top down", but schedule the code "bottom 894 // up". 895 int current_node_end = current_num_instructions(); 896 VisitNode(node); 897 if (!FinishEmittedInstructions(node, current_node_end)) return; 898 } 899 900 // We're done with the block. 901 InstructionBlock* instruction_block = 902 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); 903 instruction_block->set_code_start(static_cast<int>(instructions_.size())); 904 instruction_block->set_code_end(current_block_end); 905 906 current_block_ = nullptr; 907 } 908 909 910 void InstructionSelector::VisitControl(BasicBlock* block) { 911 #ifdef DEBUG 912 // SSA deconstruction requires targets of branches not to have phis. 913 // Edge split form guarantees this property, but is more strict. 914 if (block->SuccessorCount() > 1) { 915 for (BasicBlock* const successor : block->successors()) { 916 for (Node* const node : *successor) { 917 // If this CHECK fails, you might have specified merged variables 918 // for a label with only one predecessor. 919 CHECK(!IrOpcode::IsPhiOpcode(node->opcode())); 920 } 921 } 922 } 923 #endif 924 925 Node* input = block->control_input(); 926 switch (block->control()) { 927 case BasicBlock::kGoto: 928 return VisitGoto(block->SuccessorAt(0)); 929 case BasicBlock::kCall: { 930 DCHECK_EQ(IrOpcode::kCall, input->opcode()); 931 BasicBlock* success = block->SuccessorAt(0); 932 BasicBlock* exception = block->SuccessorAt(1); 933 return VisitCall(input, exception), VisitGoto(success); 934 } 935 case BasicBlock::kTailCall: { 936 DCHECK_EQ(IrOpcode::kTailCall, input->opcode()); 937 return VisitTailCall(input); 938 } 939 case BasicBlock::kBranch: { 940 DCHECK_EQ(IrOpcode::kBranch, input->opcode()); 941 BasicBlock* tbranch = block->SuccessorAt(0); 942 BasicBlock* fbranch = block->SuccessorAt(1); 943 if (tbranch == fbranch) return VisitGoto(tbranch); 944 return VisitBranch(input, tbranch, fbranch); 945 } 946 case BasicBlock::kSwitch: { 947 DCHECK_EQ(IrOpcode::kSwitch, input->opcode()); 948 SwitchInfo sw; 949 // Last successor must be Default. 950 sw.default_branch = block->successors().back(); 951 DCHECK_EQ(IrOpcode::kIfDefault, sw.default_branch->front()->opcode()); 952 // All other successors must be cases. 953 sw.case_count = block->SuccessorCount() - 1; 954 sw.case_branches = &block->successors().front(); 955 // Determine case values and their min/max. 956 sw.case_values = zone()->NewArray<int32_t>(sw.case_count); 957 sw.min_value = std::numeric_limits<int32_t>::max(); 958 sw.max_value = std::numeric_limits<int32_t>::min(); 959 for (size_t index = 0; index < sw.case_count; ++index) { 960 BasicBlock* branch = sw.case_branches[index]; 961 int32_t value = OpParameter<int32_t>(branch->front()->op()); 962 sw.case_values[index] = value; 963 if (sw.min_value > value) sw.min_value = value; 964 if (sw.max_value < value) sw.max_value = value; 965 } 966 DCHECK_LE(sw.min_value, sw.max_value); 967 // Note that {value_range} can be 0 if {min_value} is -2^31 and 968 // {max_value} 969 // is 2^31-1, so don't assume that it's non-zero below. 970 sw.value_range = 1u + bit_cast<uint32_t>(sw.max_value) - 971 bit_cast<uint32_t>(sw.min_value); 972 return VisitSwitch(input, sw); 973 } 974 case BasicBlock::kReturn: { 975 DCHECK_EQ(IrOpcode::kReturn, input->opcode()); 976 return VisitReturn(input); 977 } 978 case BasicBlock::kDeoptimize: { 979 DeoptimizeParameters p = DeoptimizeParametersOf(input->op()); 980 Node* value = input->InputAt(0); 981 return VisitDeoptimize(p.kind(), p.reason(), value); 982 } 983 case BasicBlock::kThrow: 984 DCHECK_EQ(IrOpcode::kThrow, input->opcode()); 985 return VisitThrow(input->InputAt(0)); 986 case BasicBlock::kNone: { 987 // Exit block doesn't have control. 988 DCHECK_NULL(input); 989 break; 990 } 991 default: 992 UNREACHABLE(); 993 break; 994 } 995 } 996 997 void InstructionSelector::MarkPairProjectionsAsWord32(Node* node) { 998 Node* projection0 = NodeProperties::FindProjection(node, 0); 999 if (projection0) { 1000 MarkAsWord32(projection0); 1001 } 1002 Node* projection1 = NodeProperties::FindProjection(node, 1); 1003 if (projection1) { 1004 MarkAsWord32(projection1); 1005 } 1006 } 1007 1008 void InstructionSelector::VisitNode(Node* node) { 1009 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes. 1010 switch (node->opcode()) { 1011 case IrOpcode::kStart: 1012 case IrOpcode::kLoop: 1013 case IrOpcode::kEnd: 1014 case IrOpcode::kBranch: 1015 case IrOpcode::kIfTrue: 1016 case IrOpcode::kIfFalse: 1017 case IrOpcode::kIfSuccess: 1018 case IrOpcode::kSwitch: 1019 case IrOpcode::kIfValue: 1020 case IrOpcode::kIfDefault: 1021 case IrOpcode::kEffectPhi: 1022 case IrOpcode::kMerge: 1023 case IrOpcode::kTerminate: 1024 case IrOpcode::kBeginRegion: 1025 // No code needed for these graph artifacts. 1026 return; 1027 case IrOpcode::kIfException: 1028 return MarkAsReference(node), VisitIfException(node); 1029 case IrOpcode::kFinishRegion: 1030 return MarkAsReference(node), VisitFinishRegion(node); 1031 case IrOpcode::kParameter: { 1032 MachineType type = 1033 linkage()->GetParameterType(ParameterIndexOf(node->op())); 1034 MarkAsRepresentation(type.representation(), node); 1035 return VisitParameter(node); 1036 } 1037 case IrOpcode::kOsrValue: 1038 return MarkAsReference(node), VisitOsrValue(node); 1039 case IrOpcode::kPhi: { 1040 MachineRepresentation rep = PhiRepresentationOf(node->op()); 1041 if (rep == MachineRepresentation::kNone) return; 1042 MarkAsRepresentation(rep, node); 1043 return VisitPhi(node); 1044 } 1045 case IrOpcode::kProjection: 1046 return VisitProjection(node); 1047 case IrOpcode::kInt32Constant: 1048 case IrOpcode::kInt64Constant: 1049 case IrOpcode::kExternalConstant: 1050 case IrOpcode::kRelocatableInt32Constant: 1051 case IrOpcode::kRelocatableInt64Constant: 1052 return VisitConstant(node); 1053 case IrOpcode::kFloat32Constant: 1054 return MarkAsFloat32(node), VisitConstant(node); 1055 case IrOpcode::kFloat64Constant: 1056 return MarkAsFloat64(node), VisitConstant(node); 1057 case IrOpcode::kHeapConstant: 1058 return MarkAsReference(node), VisitConstant(node); 1059 case IrOpcode::kNumberConstant: { 1060 double value = OpParameter<double>(node); 1061 if (!IsSmiDouble(value)) MarkAsReference(node); 1062 return VisitConstant(node); 1063 } 1064 case IrOpcode::kCall: 1065 return VisitCall(node); 1066 case IrOpcode::kDeoptimizeIf: 1067 return VisitDeoptimizeIf(node); 1068 case IrOpcode::kDeoptimizeUnless: 1069 return VisitDeoptimizeUnless(node); 1070 case IrOpcode::kTrapIf: 1071 return VisitTrapIf(node, static_cast<Runtime::FunctionId>( 1072 OpParameter<int32_t>(node->op()))); 1073 case IrOpcode::kTrapUnless: 1074 return VisitTrapUnless(node, static_cast<Runtime::FunctionId>( 1075 OpParameter<int32_t>(node->op()))); 1076 case IrOpcode::kFrameState: 1077 case IrOpcode::kStateValues: 1078 case IrOpcode::kObjectState: 1079 return; 1080 case IrOpcode::kDebugBreak: 1081 VisitDebugBreak(node); 1082 return; 1083 case IrOpcode::kComment: 1084 VisitComment(node); 1085 return; 1086 case IrOpcode::kRetain: 1087 VisitRetain(node); 1088 return; 1089 case IrOpcode::kLoad: { 1090 LoadRepresentation type = LoadRepresentationOf(node->op()); 1091 MarkAsRepresentation(type.representation(), node); 1092 return VisitLoad(node); 1093 } 1094 case IrOpcode::kStore: 1095 return VisitStore(node); 1096 case IrOpcode::kProtectedStore: 1097 return VisitProtectedStore(node); 1098 case IrOpcode::kWord32And: 1099 return MarkAsWord32(node), VisitWord32And(node); 1100 case IrOpcode::kWord32Or: 1101 return MarkAsWord32(node), VisitWord32Or(node); 1102 case IrOpcode::kWord32Xor: 1103 return MarkAsWord32(node), VisitWord32Xor(node); 1104 case IrOpcode::kWord32Shl: 1105 return MarkAsWord32(node), VisitWord32Shl(node); 1106 case IrOpcode::kWord32Shr: 1107 return MarkAsWord32(node), VisitWord32Shr(node); 1108 case IrOpcode::kWord32Sar: 1109 return MarkAsWord32(node), VisitWord32Sar(node); 1110 case IrOpcode::kWord32Ror: 1111 return MarkAsWord32(node), VisitWord32Ror(node); 1112 case IrOpcode::kWord32Equal: 1113 return VisitWord32Equal(node); 1114 case IrOpcode::kWord32Clz: 1115 return MarkAsWord32(node), VisitWord32Clz(node); 1116 case IrOpcode::kWord32Ctz: 1117 return MarkAsWord32(node), VisitWord32Ctz(node); 1118 case IrOpcode::kWord32ReverseBits: 1119 return MarkAsWord32(node), VisitWord32ReverseBits(node); 1120 case IrOpcode::kWord32ReverseBytes: 1121 return MarkAsWord32(node), VisitWord32ReverseBytes(node); 1122 case IrOpcode::kWord32Popcnt: 1123 return MarkAsWord32(node), VisitWord32Popcnt(node); 1124 case IrOpcode::kWord64Popcnt: 1125 return MarkAsWord32(node), VisitWord64Popcnt(node); 1126 case IrOpcode::kWord64And: 1127 return MarkAsWord64(node), VisitWord64And(node); 1128 case IrOpcode::kWord64Or: 1129 return MarkAsWord64(node), VisitWord64Or(node); 1130 case IrOpcode::kWord64Xor: 1131 return MarkAsWord64(node), VisitWord64Xor(node); 1132 case IrOpcode::kWord64Shl: 1133 return MarkAsWord64(node), VisitWord64Shl(node); 1134 case IrOpcode::kWord64Shr: 1135 return MarkAsWord64(node), VisitWord64Shr(node); 1136 case IrOpcode::kWord64Sar: 1137 return MarkAsWord64(node), VisitWord64Sar(node); 1138 case IrOpcode::kWord64Ror: 1139 return MarkAsWord64(node), VisitWord64Ror(node); 1140 case IrOpcode::kWord64Clz: 1141 return MarkAsWord64(node), VisitWord64Clz(node); 1142 case IrOpcode::kWord64Ctz: 1143 return MarkAsWord64(node), VisitWord64Ctz(node); 1144 case IrOpcode::kWord64ReverseBits: 1145 return MarkAsWord64(node), VisitWord64ReverseBits(node); 1146 case IrOpcode::kWord64ReverseBytes: 1147 return MarkAsWord64(node), VisitWord64ReverseBytes(node); 1148 case IrOpcode::kWord64Equal: 1149 return VisitWord64Equal(node); 1150 case IrOpcode::kInt32Add: 1151 return MarkAsWord32(node), VisitInt32Add(node); 1152 case IrOpcode::kInt32AddWithOverflow: 1153 return MarkAsWord32(node), VisitInt32AddWithOverflow(node); 1154 case IrOpcode::kInt32Sub: 1155 return MarkAsWord32(node), VisitInt32Sub(node); 1156 case IrOpcode::kInt32SubWithOverflow: 1157 return VisitInt32SubWithOverflow(node); 1158 case IrOpcode::kInt32Mul: 1159 return MarkAsWord32(node), VisitInt32Mul(node); 1160 case IrOpcode::kInt32MulWithOverflow: 1161 return MarkAsWord32(node), VisitInt32MulWithOverflow(node); 1162 case IrOpcode::kInt32MulHigh: 1163 return VisitInt32MulHigh(node); 1164 case IrOpcode::kInt32Div: 1165 return MarkAsWord32(node), VisitInt32Div(node); 1166 case IrOpcode::kInt32Mod: 1167 return MarkAsWord32(node), VisitInt32Mod(node); 1168 case IrOpcode::kInt32LessThan: 1169 return VisitInt32LessThan(node); 1170 case IrOpcode::kInt32LessThanOrEqual: 1171 return VisitInt32LessThanOrEqual(node); 1172 case IrOpcode::kUint32Div: 1173 return MarkAsWord32(node), VisitUint32Div(node); 1174 case IrOpcode::kUint32LessThan: 1175 return VisitUint32LessThan(node); 1176 case IrOpcode::kUint32LessThanOrEqual: 1177 return VisitUint32LessThanOrEqual(node); 1178 case IrOpcode::kUint32Mod: 1179 return MarkAsWord32(node), VisitUint32Mod(node); 1180 case IrOpcode::kUint32MulHigh: 1181 return VisitUint32MulHigh(node); 1182 case IrOpcode::kInt64Add: 1183 return MarkAsWord64(node), VisitInt64Add(node); 1184 case IrOpcode::kInt64AddWithOverflow: 1185 return MarkAsWord64(node), VisitInt64AddWithOverflow(node); 1186 case IrOpcode::kInt64Sub: 1187 return MarkAsWord64(node), VisitInt64Sub(node); 1188 case IrOpcode::kInt64SubWithOverflow: 1189 return MarkAsWord64(node), VisitInt64SubWithOverflow(node); 1190 case IrOpcode::kInt64Mul: 1191 return MarkAsWord64(node), VisitInt64Mul(node); 1192 case IrOpcode::kInt64Div: 1193 return MarkAsWord64(node), VisitInt64Div(node); 1194 case IrOpcode::kInt64Mod: 1195 return MarkAsWord64(node), VisitInt64Mod(node); 1196 case IrOpcode::kInt64LessThan: 1197 return VisitInt64LessThan(node); 1198 case IrOpcode::kInt64LessThanOrEqual: 1199 return VisitInt64LessThanOrEqual(node); 1200 case IrOpcode::kUint64Div: 1201 return MarkAsWord64(node), VisitUint64Div(node); 1202 case IrOpcode::kUint64LessThan: 1203 return VisitUint64LessThan(node); 1204 case IrOpcode::kUint64LessThanOrEqual: 1205 return VisitUint64LessThanOrEqual(node); 1206 case IrOpcode::kUint64Mod: 1207 return MarkAsWord64(node), VisitUint64Mod(node); 1208 case IrOpcode::kBitcastTaggedToWord: 1209 return MarkAsRepresentation(MachineType::PointerRepresentation(), node), 1210 VisitBitcastTaggedToWord(node); 1211 case IrOpcode::kBitcastWordToTagged: 1212 return MarkAsReference(node), VisitBitcastWordToTagged(node); 1213 case IrOpcode::kBitcastWordToTaggedSigned: 1214 return MarkAsRepresentation(MachineRepresentation::kTaggedSigned, node), 1215 EmitIdentity(node); 1216 case IrOpcode::kChangeFloat32ToFloat64: 1217 return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node); 1218 case IrOpcode::kChangeInt32ToFloat64: 1219 return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node); 1220 case IrOpcode::kChangeUint32ToFloat64: 1221 return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node); 1222 case IrOpcode::kChangeFloat64ToInt32: 1223 return MarkAsWord32(node), VisitChangeFloat64ToInt32(node); 1224 case IrOpcode::kChangeFloat64ToUint32: 1225 return MarkAsWord32(node), VisitChangeFloat64ToUint32(node); 1226 case IrOpcode::kFloat64SilenceNaN: 1227 MarkAsFloat64(node); 1228 if (CanProduceSignalingNaN(node->InputAt(0))) { 1229 return VisitFloat64SilenceNaN(node); 1230 } else { 1231 return EmitIdentity(node); 1232 } 1233 case IrOpcode::kTruncateFloat64ToUint32: 1234 return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node); 1235 case IrOpcode::kTruncateFloat32ToInt32: 1236 return MarkAsWord32(node), VisitTruncateFloat32ToInt32(node); 1237 case IrOpcode::kTruncateFloat32ToUint32: 1238 return MarkAsWord32(node), VisitTruncateFloat32ToUint32(node); 1239 case IrOpcode::kTryTruncateFloat32ToInt64: 1240 return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node); 1241 case IrOpcode::kTryTruncateFloat64ToInt64: 1242 return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node); 1243 case IrOpcode::kTryTruncateFloat32ToUint64: 1244 return MarkAsWord64(node), VisitTryTruncateFloat32ToUint64(node); 1245 case IrOpcode::kTryTruncateFloat64ToUint64: 1246 return MarkAsWord64(node), VisitTryTruncateFloat64ToUint64(node); 1247 case IrOpcode::kChangeInt32ToInt64: 1248 return MarkAsWord64(node), VisitChangeInt32ToInt64(node); 1249 case IrOpcode::kChangeUint32ToUint64: 1250 return MarkAsWord64(node), VisitChangeUint32ToUint64(node); 1251 case IrOpcode::kTruncateFloat64ToFloat32: 1252 return MarkAsFloat32(node), VisitTruncateFloat64ToFloat32(node); 1253 case IrOpcode::kTruncateFloat64ToWord32: 1254 return MarkAsWord32(node), VisitTruncateFloat64ToWord32(node); 1255 case IrOpcode::kTruncateInt64ToInt32: 1256 return MarkAsWord32(node), VisitTruncateInt64ToInt32(node); 1257 case IrOpcode::kRoundFloat64ToInt32: 1258 return MarkAsWord32(node), VisitRoundFloat64ToInt32(node); 1259 case IrOpcode::kRoundInt64ToFloat32: 1260 return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node); 1261 case IrOpcode::kRoundInt32ToFloat32: 1262 return MarkAsFloat32(node), VisitRoundInt32ToFloat32(node); 1263 case IrOpcode::kRoundInt64ToFloat64: 1264 return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node); 1265 case IrOpcode::kBitcastFloat32ToInt32: 1266 return MarkAsWord32(node), VisitBitcastFloat32ToInt32(node); 1267 case IrOpcode::kRoundUint32ToFloat32: 1268 return MarkAsFloat32(node), VisitRoundUint32ToFloat32(node); 1269 case IrOpcode::kRoundUint64ToFloat32: 1270 return MarkAsFloat64(node), VisitRoundUint64ToFloat32(node); 1271 case IrOpcode::kRoundUint64ToFloat64: 1272 return MarkAsFloat64(node), VisitRoundUint64ToFloat64(node); 1273 case IrOpcode::kBitcastFloat64ToInt64: 1274 return MarkAsWord64(node), VisitBitcastFloat64ToInt64(node); 1275 case IrOpcode::kBitcastInt32ToFloat32: 1276 return MarkAsFloat32(node), VisitBitcastInt32ToFloat32(node); 1277 case IrOpcode::kBitcastInt64ToFloat64: 1278 return MarkAsFloat64(node), VisitBitcastInt64ToFloat64(node); 1279 case IrOpcode::kFloat32Add: 1280 return MarkAsFloat32(node), VisitFloat32Add(node); 1281 case IrOpcode::kFloat32Sub: 1282 return MarkAsFloat32(node), VisitFloat32Sub(node); 1283 case IrOpcode::kFloat32Neg: 1284 return MarkAsFloat32(node), VisitFloat32Neg(node); 1285 case IrOpcode::kFloat32Mul: 1286 return MarkAsFloat32(node), VisitFloat32Mul(node); 1287 case IrOpcode::kFloat32Div: 1288 return MarkAsFloat32(node), VisitFloat32Div(node); 1289 case IrOpcode::kFloat32Abs: 1290 return MarkAsFloat32(node), VisitFloat32Abs(node); 1291 case IrOpcode::kFloat32Sqrt: 1292 return MarkAsFloat32(node), VisitFloat32Sqrt(node); 1293 case IrOpcode::kFloat32Equal: 1294 return VisitFloat32Equal(node); 1295 case IrOpcode::kFloat32LessThan: 1296 return VisitFloat32LessThan(node); 1297 case IrOpcode::kFloat32LessThanOrEqual: 1298 return VisitFloat32LessThanOrEqual(node); 1299 case IrOpcode::kFloat32Max: 1300 return MarkAsFloat32(node), VisitFloat32Max(node); 1301 case IrOpcode::kFloat32Min: 1302 return MarkAsFloat32(node), VisitFloat32Min(node); 1303 case IrOpcode::kFloat64Add: 1304 return MarkAsFloat64(node), VisitFloat64Add(node); 1305 case IrOpcode::kFloat64Sub: 1306 return MarkAsFloat64(node), VisitFloat64Sub(node); 1307 case IrOpcode::kFloat64Neg: 1308 return MarkAsFloat64(node), VisitFloat64Neg(node); 1309 case IrOpcode::kFloat64Mul: 1310 return MarkAsFloat64(node), VisitFloat64Mul(node); 1311 case IrOpcode::kFloat64Div: 1312 return MarkAsFloat64(node), VisitFloat64Div(node); 1313 case IrOpcode::kFloat64Mod: 1314 return MarkAsFloat64(node), VisitFloat64Mod(node); 1315 case IrOpcode::kFloat64Min: 1316 return MarkAsFloat64(node), VisitFloat64Min(node); 1317 case IrOpcode::kFloat64Max: 1318 return MarkAsFloat64(node), VisitFloat64Max(node); 1319 case IrOpcode::kFloat64Abs: 1320 return MarkAsFloat64(node), VisitFloat64Abs(node); 1321 case IrOpcode::kFloat64Acos: 1322 return MarkAsFloat64(node), VisitFloat64Acos(node); 1323 case IrOpcode::kFloat64Acosh: 1324 return MarkAsFloat64(node), VisitFloat64Acosh(node); 1325 case IrOpcode::kFloat64Asin: 1326 return MarkAsFloat64(node), VisitFloat64Asin(node); 1327 case IrOpcode::kFloat64Asinh: 1328 return MarkAsFloat64(node), VisitFloat64Asinh(node); 1329 case IrOpcode::kFloat64Atan: 1330 return MarkAsFloat64(node), VisitFloat64Atan(node); 1331 case IrOpcode::kFloat64Atanh: 1332 return MarkAsFloat64(node), VisitFloat64Atanh(node); 1333 case IrOpcode::kFloat64Atan2: 1334 return MarkAsFloat64(node), VisitFloat64Atan2(node); 1335 case IrOpcode::kFloat64Cbrt: 1336 return MarkAsFloat64(node), VisitFloat64Cbrt(node); 1337 case IrOpcode::kFloat64Cos: 1338 return MarkAsFloat64(node), VisitFloat64Cos(node); 1339 case IrOpcode::kFloat64Cosh: 1340 return MarkAsFloat64(node), VisitFloat64Cosh(node); 1341 case IrOpcode::kFloat64Exp: 1342 return MarkAsFloat64(node), VisitFloat64Exp(node); 1343 case IrOpcode::kFloat64Expm1: 1344 return MarkAsFloat64(node), VisitFloat64Expm1(node); 1345 case IrOpcode::kFloat64Log: 1346 return MarkAsFloat64(node), VisitFloat64Log(node); 1347 case IrOpcode::kFloat64Log1p: 1348 return MarkAsFloat64(node), VisitFloat64Log1p(node); 1349 case IrOpcode::kFloat64Log10: 1350 return MarkAsFloat64(node), VisitFloat64Log10(node); 1351 case IrOpcode::kFloat64Log2: 1352 return MarkAsFloat64(node), VisitFloat64Log2(node); 1353 case IrOpcode::kFloat64Pow: 1354 return MarkAsFloat64(node), VisitFloat64Pow(node); 1355 case IrOpcode::kFloat64Sin: 1356 return MarkAsFloat64(node), VisitFloat64Sin(node); 1357 case IrOpcode::kFloat64Sinh: 1358 return MarkAsFloat64(node), VisitFloat64Sinh(node); 1359 case IrOpcode::kFloat64Sqrt: 1360 return MarkAsFloat64(node), VisitFloat64Sqrt(node); 1361 case IrOpcode::kFloat64Tan: 1362 return MarkAsFloat64(node), VisitFloat64Tan(node); 1363 case IrOpcode::kFloat64Tanh: 1364 return MarkAsFloat64(node), VisitFloat64Tanh(node); 1365 case IrOpcode::kFloat64Equal: 1366 return VisitFloat64Equal(node); 1367 case IrOpcode::kFloat64LessThan: 1368 return VisitFloat64LessThan(node); 1369 case IrOpcode::kFloat64LessThanOrEqual: 1370 return VisitFloat64LessThanOrEqual(node); 1371 case IrOpcode::kFloat32RoundDown: 1372 return MarkAsFloat32(node), VisitFloat32RoundDown(node); 1373 case IrOpcode::kFloat64RoundDown: 1374 return MarkAsFloat64(node), VisitFloat64RoundDown(node); 1375 case IrOpcode::kFloat32RoundUp: 1376 return MarkAsFloat32(node), VisitFloat32RoundUp(node); 1377 case IrOpcode::kFloat64RoundUp: 1378 return MarkAsFloat64(node), VisitFloat64RoundUp(node); 1379 case IrOpcode::kFloat32RoundTruncate: 1380 return MarkAsFloat32(node), VisitFloat32RoundTruncate(node); 1381 case IrOpcode::kFloat64RoundTruncate: 1382 return MarkAsFloat64(node), VisitFloat64RoundTruncate(node); 1383 case IrOpcode::kFloat64RoundTiesAway: 1384 return MarkAsFloat64(node), VisitFloat64RoundTiesAway(node); 1385 case IrOpcode::kFloat32RoundTiesEven: 1386 return MarkAsFloat32(node), VisitFloat32RoundTiesEven(node); 1387 case IrOpcode::kFloat64RoundTiesEven: 1388 return MarkAsFloat64(node), VisitFloat64RoundTiesEven(node); 1389 case IrOpcode::kFloat64ExtractLowWord32: 1390 return MarkAsWord32(node), VisitFloat64ExtractLowWord32(node); 1391 case IrOpcode::kFloat64ExtractHighWord32: 1392 return MarkAsWord32(node), VisitFloat64ExtractHighWord32(node); 1393 case IrOpcode::kFloat64InsertLowWord32: 1394 return MarkAsFloat64(node), VisitFloat64InsertLowWord32(node); 1395 case IrOpcode::kFloat64InsertHighWord32: 1396 return MarkAsFloat64(node), VisitFloat64InsertHighWord32(node); 1397 case IrOpcode::kStackSlot: 1398 return VisitStackSlot(node); 1399 case IrOpcode::kLoadStackPointer: 1400 return VisitLoadStackPointer(node); 1401 case IrOpcode::kLoadFramePointer: 1402 return VisitLoadFramePointer(node); 1403 case IrOpcode::kLoadParentFramePointer: 1404 return VisitLoadParentFramePointer(node); 1405 case IrOpcode::kUnalignedLoad: { 1406 UnalignedLoadRepresentation type = 1407 UnalignedLoadRepresentationOf(node->op()); 1408 MarkAsRepresentation(type.representation(), node); 1409 return VisitUnalignedLoad(node); 1410 } 1411 case IrOpcode::kUnalignedStore: 1412 return VisitUnalignedStore(node); 1413 case IrOpcode::kCheckedLoad: { 1414 MachineRepresentation rep = 1415 CheckedLoadRepresentationOf(node->op()).representation(); 1416 MarkAsRepresentation(rep, node); 1417 return VisitCheckedLoad(node); 1418 } 1419 case IrOpcode::kCheckedStore: 1420 return VisitCheckedStore(node); 1421 case IrOpcode::kInt32PairAdd: 1422 MarkAsWord32(node); 1423 MarkPairProjectionsAsWord32(node); 1424 return VisitInt32PairAdd(node); 1425 case IrOpcode::kInt32PairSub: 1426 MarkAsWord32(node); 1427 MarkPairProjectionsAsWord32(node); 1428 return VisitInt32PairSub(node); 1429 case IrOpcode::kInt32PairMul: 1430 MarkAsWord32(node); 1431 MarkPairProjectionsAsWord32(node); 1432 return VisitInt32PairMul(node); 1433 case IrOpcode::kWord32PairShl: 1434 MarkAsWord32(node); 1435 MarkPairProjectionsAsWord32(node); 1436 return VisitWord32PairShl(node); 1437 case IrOpcode::kWord32PairShr: 1438 MarkAsWord32(node); 1439 MarkPairProjectionsAsWord32(node); 1440 return VisitWord32PairShr(node); 1441 case IrOpcode::kWord32PairSar: 1442 MarkAsWord32(node); 1443 MarkPairProjectionsAsWord32(node); 1444 return VisitWord32PairSar(node); 1445 case IrOpcode::kAtomicLoad: { 1446 LoadRepresentation type = LoadRepresentationOf(node->op()); 1447 MarkAsRepresentation(type.representation(), node); 1448 return VisitAtomicLoad(node); 1449 } 1450 case IrOpcode::kAtomicStore: 1451 return VisitAtomicStore(node); 1452 case IrOpcode::kProtectedLoad: { 1453 LoadRepresentation type = LoadRepresentationOf(node->op()); 1454 MarkAsRepresentation(type.representation(), node); 1455 return VisitProtectedLoad(node); 1456 } 1457 case IrOpcode::kUnsafePointerAdd: 1458 MarkAsRepresentation(MachineType::PointerRepresentation(), node); 1459 return VisitUnsafePointerAdd(node); 1460 case IrOpcode::kCreateFloat32x4: 1461 return MarkAsSimd128(node), VisitCreateFloat32x4(node); 1462 case IrOpcode::kFloat32x4ExtractLane: 1463 return MarkAsFloat32(node), VisitFloat32x4ExtractLane(node); 1464 case IrOpcode::kFloat32x4ReplaceLane: 1465 return MarkAsSimd128(node), VisitFloat32x4ReplaceLane(node); 1466 case IrOpcode::kFloat32x4FromInt32x4: 1467 return MarkAsSimd128(node), VisitFloat32x4FromInt32x4(node); 1468 case IrOpcode::kFloat32x4FromUint32x4: 1469 return MarkAsSimd128(node), VisitFloat32x4FromUint32x4(node); 1470 case IrOpcode::kFloat32x4Abs: 1471 return MarkAsSimd128(node), VisitFloat32x4Abs(node); 1472 case IrOpcode::kFloat32x4Neg: 1473 return MarkAsSimd128(node), VisitFloat32x4Neg(node); 1474 case IrOpcode::kFloat32x4Add: 1475 return MarkAsSimd128(node), VisitFloat32x4Add(node); 1476 case IrOpcode::kFloat32x4Sub: 1477 return MarkAsSimd128(node), VisitFloat32x4Sub(node); 1478 case IrOpcode::kFloat32x4Equal: 1479 return MarkAsSimd1x4(node), VisitFloat32x4Equal(node); 1480 case IrOpcode::kFloat32x4NotEqual: 1481 return MarkAsSimd1x4(node), VisitFloat32x4NotEqual(node); 1482 case IrOpcode::kCreateInt32x4: 1483 return MarkAsSimd128(node), VisitCreateInt32x4(node); 1484 case IrOpcode::kInt32x4ExtractLane: 1485 return MarkAsWord32(node), VisitInt32x4ExtractLane(node); 1486 case IrOpcode::kInt32x4ReplaceLane: 1487 return MarkAsSimd128(node), VisitInt32x4ReplaceLane(node); 1488 case IrOpcode::kInt32x4FromFloat32x4: 1489 return MarkAsSimd128(node), VisitInt32x4FromFloat32x4(node); 1490 case IrOpcode::kUint32x4FromFloat32x4: 1491 return MarkAsSimd128(node), VisitUint32x4FromFloat32x4(node); 1492 case IrOpcode::kInt32x4Neg: 1493 return MarkAsSimd128(node), VisitInt32x4Neg(node); 1494 case IrOpcode::kInt32x4ShiftLeftByScalar: 1495 return MarkAsSimd128(node), VisitInt32x4ShiftLeftByScalar(node); 1496 case IrOpcode::kInt32x4ShiftRightByScalar: 1497 return MarkAsSimd128(node), VisitInt32x4ShiftRightByScalar(node); 1498 case IrOpcode::kInt32x4Add: 1499 return MarkAsSimd128(node), VisitInt32x4Add(node); 1500 case IrOpcode::kInt32x4Sub: 1501 return MarkAsSimd128(node), VisitInt32x4Sub(node); 1502 case IrOpcode::kInt32x4Mul: 1503 return MarkAsSimd128(node), VisitInt32x4Mul(node); 1504 case IrOpcode::kInt32x4Min: 1505 return MarkAsSimd128(node), VisitInt32x4Min(node); 1506 case IrOpcode::kInt32x4Max: 1507 return MarkAsSimd128(node), VisitInt32x4Max(node); 1508 case IrOpcode::kInt32x4Equal: 1509 return MarkAsSimd1x4(node), VisitInt32x4Equal(node); 1510 case IrOpcode::kInt32x4NotEqual: 1511 return MarkAsSimd1x4(node), VisitInt32x4NotEqual(node); 1512 case IrOpcode::kInt32x4GreaterThan: 1513 return MarkAsSimd1x4(node), VisitInt32x4GreaterThan(node); 1514 case IrOpcode::kInt32x4GreaterThanOrEqual: 1515 return MarkAsSimd1x4(node), VisitInt32x4GreaterThanOrEqual(node); 1516 case IrOpcode::kUint32x4ShiftRightByScalar: 1517 return MarkAsSimd128(node), VisitUint32x4ShiftRightByScalar(node); 1518 case IrOpcode::kUint32x4Min: 1519 return MarkAsSimd128(node), VisitUint32x4Min(node); 1520 case IrOpcode::kUint32x4Max: 1521 return MarkAsSimd128(node), VisitUint32x4Max(node); 1522 case IrOpcode::kUint32x4GreaterThan: 1523 return MarkAsSimd1x4(node), VisitUint32x4GreaterThan(node); 1524 case IrOpcode::kUint32x4GreaterThanOrEqual: 1525 return MarkAsSimd1x4(node), VisitUint32x4GreaterThanOrEqual(node); 1526 case IrOpcode::kCreateInt16x8: 1527 return MarkAsSimd128(node), VisitCreateInt16x8(node); 1528 case IrOpcode::kInt16x8ExtractLane: 1529 return MarkAsWord32(node), VisitInt16x8ExtractLane(node); 1530 case IrOpcode::kInt16x8ReplaceLane: 1531 return MarkAsSimd128(node), VisitInt16x8ReplaceLane(node); 1532 case IrOpcode::kInt16x8Neg: 1533 return MarkAsSimd128(node), VisitInt16x8Neg(node); 1534 case IrOpcode::kInt16x8ShiftLeftByScalar: 1535 return MarkAsSimd128(node), VisitInt16x8ShiftLeftByScalar(node); 1536 case IrOpcode::kInt16x8ShiftRightByScalar: 1537 return MarkAsSimd128(node), VisitInt16x8ShiftRightByScalar(node); 1538 case IrOpcode::kInt16x8Add: 1539 return MarkAsSimd128(node), VisitInt16x8Add(node); 1540 case IrOpcode::kInt16x8AddSaturate: 1541 return MarkAsSimd128(node), VisitInt16x8AddSaturate(node); 1542 case IrOpcode::kInt16x8Sub: 1543 return MarkAsSimd128(node), VisitInt16x8Sub(node); 1544 case IrOpcode::kInt16x8SubSaturate: 1545 return MarkAsSimd128(node), VisitInt16x8SubSaturate(node); 1546 case IrOpcode::kInt16x8Mul: 1547 return MarkAsSimd128(node), VisitInt16x8Mul(node); 1548 case IrOpcode::kInt16x8Min: 1549 return MarkAsSimd128(node), VisitInt16x8Min(node); 1550 case IrOpcode::kInt16x8Max: 1551 return MarkAsSimd128(node), VisitInt16x8Max(node); 1552 case IrOpcode::kInt16x8Equal: 1553 return MarkAsSimd1x8(node), VisitInt16x8Equal(node); 1554 case IrOpcode::kInt16x8NotEqual: 1555 return MarkAsSimd1x8(node), VisitInt16x8NotEqual(node); 1556 case IrOpcode::kInt16x8GreaterThan: 1557 return MarkAsSimd1x8(node), VisitInt16x8GreaterThan(node); 1558 case IrOpcode::kInt16x8GreaterThanOrEqual: 1559 return MarkAsSimd1x8(node), VisitInt16x8GreaterThanOrEqual(node); 1560 case IrOpcode::kUint16x8ShiftRightByScalar: 1561 return MarkAsSimd128(node), VisitUint16x8ShiftRightByScalar(node); 1562 case IrOpcode::kUint16x8AddSaturate: 1563 return MarkAsSimd128(node), VisitUint16x8AddSaturate(node); 1564 case IrOpcode::kUint16x8SubSaturate: 1565 return MarkAsSimd128(node), VisitUint16x8SubSaturate(node); 1566 case IrOpcode::kUint16x8Min: 1567 return MarkAsSimd128(node), VisitUint16x8Min(node); 1568 case IrOpcode::kUint16x8Max: 1569 return MarkAsSimd128(node), VisitUint16x8Max(node); 1570 case IrOpcode::kUint16x8GreaterThan: 1571 return MarkAsSimd1x8(node), VisitUint16x8GreaterThan(node); 1572 case IrOpcode::kUint16x8GreaterThanOrEqual: 1573 return MarkAsSimd1x8(node), VisitUint16x8GreaterThanOrEqual(node); 1574 case IrOpcode::kCreateInt8x16: 1575 return MarkAsSimd128(node), VisitCreateInt8x16(node); 1576 case IrOpcode::kInt8x16ExtractLane: 1577 return MarkAsWord32(node), VisitInt8x16ExtractLane(node); 1578 case IrOpcode::kInt8x16ReplaceLane: 1579 return MarkAsSimd128(node), VisitInt8x16ReplaceLane(node); 1580 case IrOpcode::kInt8x16Neg: 1581 return MarkAsSimd128(node), VisitInt8x16Neg(node); 1582 case IrOpcode::kInt8x16ShiftLeftByScalar: 1583 return MarkAsSimd128(node), VisitInt8x16ShiftLeftByScalar(node); 1584 case IrOpcode::kInt8x16ShiftRightByScalar: 1585 return MarkAsSimd128(node), VisitInt8x16ShiftRightByScalar(node); 1586 case IrOpcode::kInt8x16Add: 1587 return MarkAsSimd128(node), VisitInt8x16Add(node); 1588 case IrOpcode::kInt8x16AddSaturate: 1589 return MarkAsSimd128(node), VisitInt8x16AddSaturate(node); 1590 case IrOpcode::kInt8x16Sub: 1591 return MarkAsSimd128(node), VisitInt8x16Sub(node); 1592 case IrOpcode::kInt8x16SubSaturate: 1593 return MarkAsSimd128(node), VisitInt8x16SubSaturate(node); 1594 case IrOpcode::kInt8x16Mul: 1595 return MarkAsSimd128(node), VisitInt8x16Mul(node); 1596 case IrOpcode::kInt8x16Min: 1597 return MarkAsSimd128(node), VisitInt8x16Min(node); 1598 case IrOpcode::kInt8x16Max: 1599 return MarkAsSimd128(node), VisitInt8x16Max(node); 1600 case IrOpcode::kInt8x16Equal: 1601 return MarkAsSimd1x16(node), VisitInt8x16Equal(node); 1602 case IrOpcode::kInt8x16NotEqual: 1603 return MarkAsSimd1x16(node), VisitInt8x16NotEqual(node); 1604 case IrOpcode::kInt8x16GreaterThan: 1605 return MarkAsSimd1x16(node), VisitInt8x16GreaterThan(node); 1606 case IrOpcode::kInt8x16GreaterThanOrEqual: 1607 return MarkAsSimd1x16(node), VisitInt8x16GreaterThanOrEqual(node); 1608 case IrOpcode::kUint8x16ShiftRightByScalar: 1609 return MarkAsSimd128(node), VisitUint8x16ShiftRightByScalar(node); 1610 case IrOpcode::kUint8x16AddSaturate: 1611 return MarkAsSimd128(node), VisitUint8x16AddSaturate(node); 1612 case IrOpcode::kUint8x16SubSaturate: 1613 return MarkAsSimd128(node), VisitUint8x16SubSaturate(node); 1614 case IrOpcode::kUint8x16Min: 1615 return MarkAsSimd128(node), VisitUint8x16Min(node); 1616 case IrOpcode::kUint8x16Max: 1617 return MarkAsSimd128(node), VisitUint8x16Max(node); 1618 case IrOpcode::kUint8x16GreaterThan: 1619 return MarkAsSimd1x16(node), VisitUint8x16GreaterThan(node); 1620 case IrOpcode::kUint8x16GreaterThanOrEqual: 1621 return MarkAsSimd1x16(node), VisitUint16x8GreaterThanOrEqual(node); 1622 case IrOpcode::kSimd128And: 1623 return MarkAsSimd128(node), VisitSimd128And(node); 1624 case IrOpcode::kSimd128Or: 1625 return MarkAsSimd128(node), VisitSimd128Or(node); 1626 case IrOpcode::kSimd128Xor: 1627 return MarkAsSimd128(node), VisitSimd128Xor(node); 1628 case IrOpcode::kSimd128Not: 1629 return MarkAsSimd128(node), VisitSimd128Not(node); 1630 case IrOpcode::kSimd32x4Select: 1631 return MarkAsSimd128(node), VisitSimd32x4Select(node); 1632 case IrOpcode::kSimd16x8Select: 1633 return MarkAsSimd128(node), VisitSimd16x8Select(node); 1634 case IrOpcode::kSimd8x16Select: 1635 return MarkAsSimd128(node), VisitSimd8x16Select(node); 1636 default: 1637 V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d", 1638 node->opcode(), node->op()->mnemonic(), node->id()); 1639 break; 1640 } 1641 } 1642 1643 void InstructionSelector::VisitLoadStackPointer(Node* node) { 1644 OperandGenerator g(this); 1645 Emit(kArchStackPointer, g.DefineAsRegister(node)); 1646 } 1647 1648 void InstructionSelector::VisitLoadFramePointer(Node* node) { 1649 OperandGenerator g(this); 1650 Emit(kArchFramePointer, g.DefineAsRegister(node)); 1651 } 1652 1653 void InstructionSelector::VisitLoadParentFramePointer(Node* node) { 1654 OperandGenerator g(this); 1655 Emit(kArchParentFramePointer, g.DefineAsRegister(node)); 1656 } 1657 1658 void InstructionSelector::VisitFloat64Acos(Node* node) { 1659 VisitFloat64Ieee754Unop(node, kIeee754Float64Acos); 1660 } 1661 1662 void InstructionSelector::VisitFloat64Acosh(Node* node) { 1663 VisitFloat64Ieee754Unop(node, kIeee754Float64Acosh); 1664 } 1665 1666 void InstructionSelector::VisitFloat64Asin(Node* node) { 1667 VisitFloat64Ieee754Unop(node, kIeee754Float64Asin); 1668 } 1669 1670 void InstructionSelector::VisitFloat64Asinh(Node* node) { 1671 VisitFloat64Ieee754Unop(node, kIeee754Float64Asinh); 1672 } 1673 1674 void InstructionSelector::VisitFloat64Atan(Node* node) { 1675 VisitFloat64Ieee754Unop(node, kIeee754Float64Atan); 1676 } 1677 1678 void InstructionSelector::VisitFloat64Atanh(Node* node) { 1679 VisitFloat64Ieee754Unop(node, kIeee754Float64Atanh); 1680 } 1681 1682 void InstructionSelector::VisitFloat64Atan2(Node* node) { 1683 VisitFloat64Ieee754Binop(node, kIeee754Float64Atan2); 1684 } 1685 1686 void InstructionSelector::VisitFloat64Cbrt(Node* node) { 1687 VisitFloat64Ieee754Unop(node, kIeee754Float64Cbrt); 1688 } 1689 1690 void InstructionSelector::VisitFloat64Cos(Node* node) { 1691 VisitFloat64Ieee754Unop(node, kIeee754Float64Cos); 1692 } 1693 1694 void InstructionSelector::VisitFloat64Cosh(Node* node) { 1695 VisitFloat64Ieee754Unop(node, kIeee754Float64Cosh); 1696 } 1697 1698 void InstructionSelector::VisitFloat64Exp(Node* node) { 1699 VisitFloat64Ieee754Unop(node, kIeee754Float64Exp); 1700 } 1701 1702 void InstructionSelector::VisitFloat64Expm1(Node* node) { 1703 VisitFloat64Ieee754Unop(node, kIeee754Float64Expm1); 1704 } 1705 1706 void InstructionSelector::VisitFloat64Log(Node* node) { 1707 VisitFloat64Ieee754Unop(node, kIeee754Float64Log); 1708 } 1709 1710 void InstructionSelector::VisitFloat64Log1p(Node* node) { 1711 VisitFloat64Ieee754Unop(node, kIeee754Float64Log1p); 1712 } 1713 1714 void InstructionSelector::VisitFloat64Log2(Node* node) { 1715 VisitFloat64Ieee754Unop(node, kIeee754Float64Log2); 1716 } 1717 1718 void InstructionSelector::VisitFloat64Log10(Node* node) { 1719 VisitFloat64Ieee754Unop(node, kIeee754Float64Log10); 1720 } 1721 1722 void InstructionSelector::VisitFloat64Pow(Node* node) { 1723 VisitFloat64Ieee754Binop(node, kIeee754Float64Pow); 1724 } 1725 1726 void InstructionSelector::VisitFloat64Sin(Node* node) { 1727 VisitFloat64Ieee754Unop(node, kIeee754Float64Sin); 1728 } 1729 1730 void InstructionSelector::VisitFloat64Sinh(Node* node) { 1731 VisitFloat64Ieee754Unop(node, kIeee754Float64Sinh); 1732 } 1733 1734 void InstructionSelector::VisitFloat64Tan(Node* node) { 1735 VisitFloat64Ieee754Unop(node, kIeee754Float64Tan); 1736 } 1737 1738 void InstructionSelector::VisitFloat64Tanh(Node* node) { 1739 VisitFloat64Ieee754Unop(node, kIeee754Float64Tanh); 1740 } 1741 1742 void InstructionSelector::EmitTableSwitch(const SwitchInfo& sw, 1743 InstructionOperand& index_operand) { 1744 OperandGenerator g(this); 1745 size_t input_count = 2 + sw.value_range; 1746 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); 1747 inputs[0] = index_operand; 1748 InstructionOperand default_operand = g.Label(sw.default_branch); 1749 std::fill(&inputs[1], &inputs[input_count], default_operand); 1750 for (size_t index = 0; index < sw.case_count; ++index) { 1751 size_t value = sw.case_values[index] - sw.min_value; 1752 BasicBlock* branch = sw.case_branches[index]; 1753 DCHECK_LE(0u, value); 1754 DCHECK_LT(value + 2, input_count); 1755 inputs[value + 2] = g.Label(branch); 1756 } 1757 Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr); 1758 } 1759 1760 1761 void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw, 1762 InstructionOperand& value_operand) { 1763 OperandGenerator g(this); 1764 size_t input_count = 2 + sw.case_count * 2; 1765 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); 1766 inputs[0] = value_operand; 1767 inputs[1] = g.Label(sw.default_branch); 1768 for (size_t index = 0; index < sw.case_count; ++index) { 1769 int32_t value = sw.case_values[index]; 1770 BasicBlock* branch = sw.case_branches[index]; 1771 inputs[index * 2 + 2 + 0] = g.TempImmediate(value); 1772 inputs[index * 2 + 2 + 1] = g.Label(branch); 1773 } 1774 Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr); 1775 } 1776 1777 void InstructionSelector::VisitStackSlot(Node* node) { 1778 int size = StackSlotSizeOf(node->op()); 1779 int slot = frame_->AllocateSpillSlot(size); 1780 OperandGenerator g(this); 1781 1782 Emit(kArchStackSlot, g.DefineAsRegister(node), 1783 sequence()->AddImmediate(Constant(slot)), 0, nullptr); 1784 } 1785 1786 void InstructionSelector::VisitBitcastTaggedToWord(Node* node) { 1787 EmitIdentity(node); 1788 } 1789 1790 void InstructionSelector::VisitBitcastWordToTagged(Node* node) { 1791 OperandGenerator g(this); 1792 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(node->InputAt(0))); 1793 } 1794 1795 // 32 bit targets do not implement the following instructions. 1796 #if V8_TARGET_ARCH_32_BIT 1797 1798 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); } 1799 1800 1801 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); } 1802 1803 1804 void InstructionSelector::VisitWord64Xor(Node* node) { UNIMPLEMENTED(); } 1805 1806 1807 void InstructionSelector::VisitWord64Shl(Node* node) { UNIMPLEMENTED(); } 1808 1809 1810 void InstructionSelector::VisitWord64Shr(Node* node) { UNIMPLEMENTED(); } 1811 1812 1813 void InstructionSelector::VisitWord64Sar(Node* node) { UNIMPLEMENTED(); } 1814 1815 1816 void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); } 1817 1818 1819 void InstructionSelector::VisitWord64Clz(Node* node) { UNIMPLEMENTED(); } 1820 1821 1822 void InstructionSelector::VisitWord64Ctz(Node* node) { UNIMPLEMENTED(); } 1823 1824 1825 void InstructionSelector::VisitWord64ReverseBits(Node* node) { 1826 UNIMPLEMENTED(); 1827 } 1828 1829 1830 void InstructionSelector::VisitWord64Popcnt(Node* node) { UNIMPLEMENTED(); } 1831 1832 1833 void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); } 1834 1835 1836 void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); } 1837 1838 1839 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { 1840 UNIMPLEMENTED(); 1841 } 1842 1843 1844 void InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); } 1845 1846 1847 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { 1848 UNIMPLEMENTED(); 1849 } 1850 1851 void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); } 1852 1853 1854 void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); } 1855 1856 1857 void InstructionSelector::VisitInt64LessThan(Node* node) { UNIMPLEMENTED(); } 1858 1859 1860 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { 1861 UNIMPLEMENTED(); 1862 } 1863 1864 1865 void InstructionSelector::VisitUint64Div(Node* node) { UNIMPLEMENTED(); } 1866 1867 1868 void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); } 1869 1870 1871 void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); } 1872 1873 1874 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { 1875 UNIMPLEMENTED(); 1876 } 1877 1878 1879 void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); } 1880 1881 1882 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) { 1883 UNIMPLEMENTED(); 1884 } 1885 1886 1887 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { 1888 UNIMPLEMENTED(); 1889 } 1890 1891 1892 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) { 1893 UNIMPLEMENTED(); 1894 } 1895 1896 1897 void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) { 1898 UNIMPLEMENTED(); 1899 } 1900 1901 1902 void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) { 1903 UNIMPLEMENTED(); 1904 } 1905 1906 1907 void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) { 1908 UNIMPLEMENTED(); 1909 } 1910 1911 1912 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { 1913 UNIMPLEMENTED(); 1914 } 1915 1916 1917 void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) { 1918 UNIMPLEMENTED(); 1919 } 1920 1921 1922 void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) { 1923 UNIMPLEMENTED(); 1924 } 1925 1926 1927 void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) { 1928 UNIMPLEMENTED(); 1929 } 1930 1931 1932 void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) { 1933 UNIMPLEMENTED(); 1934 } 1935 1936 void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) { 1937 UNIMPLEMENTED(); 1938 } 1939 1940 1941 void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) { 1942 UNIMPLEMENTED(); 1943 } 1944 #endif // V8_TARGET_ARCH_32_BIT 1945 1946 // 64 bit targets do not implement the following instructions. 1947 #if V8_TARGET_ARCH_64_BIT 1948 void InstructionSelector::VisitInt32PairAdd(Node* node) { UNIMPLEMENTED(); } 1949 1950 void InstructionSelector::VisitInt32PairSub(Node* node) { UNIMPLEMENTED(); } 1951 1952 void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); } 1953 1954 void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); } 1955 1956 void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); } 1957 1958 void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); } 1959 #endif // V8_TARGET_ARCH_64_BIT 1960 1961 #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM 1962 void InstructionSelector::VisitCreateInt32x4(Node* node) { UNIMPLEMENTED(); } 1963 1964 void InstructionSelector::VisitInt32x4ExtractLane(Node* node) { 1965 UNIMPLEMENTED(); 1966 } 1967 1968 void InstructionSelector::VisitInt32x4ReplaceLane(Node* node) { 1969 UNIMPLEMENTED(); 1970 } 1971 1972 void InstructionSelector::VisitInt32x4Add(Node* node) { UNIMPLEMENTED(); } 1973 1974 void InstructionSelector::VisitInt32x4Sub(Node* node) { UNIMPLEMENTED(); } 1975 1976 #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM 1977 1978 #if !V8_TARGET_ARCH_ARM 1979 void InstructionSelector::VisitCreateFloat32x4(Node* node) { UNIMPLEMENTED(); } 1980 1981 void InstructionSelector::VisitFloat32x4ExtractLane(Node* node) { 1982 UNIMPLEMENTED(); 1983 } 1984 1985 void InstructionSelector::VisitFloat32x4ReplaceLane(Node* node) { 1986 UNIMPLEMENTED(); 1987 } 1988 1989 void InstructionSelector::VisitFloat32x4FromInt32x4(Node* node) { 1990 UNIMPLEMENTED(); 1991 } 1992 1993 void InstructionSelector::VisitFloat32x4FromUint32x4(Node* node) { 1994 UNIMPLEMENTED(); 1995 } 1996 1997 void InstructionSelector::VisitFloat32x4Abs(Node* node) { UNIMPLEMENTED(); } 1998 1999 void InstructionSelector::VisitFloat32x4Neg(Node* node) { UNIMPLEMENTED(); } 2000 2001 void InstructionSelector::VisitFloat32x4Add(Node* node) { UNIMPLEMENTED(); } 2002 2003 void InstructionSelector::VisitFloat32x4Sub(Node* node) { UNIMPLEMENTED(); } 2004 2005 void InstructionSelector::VisitFloat32x4Equal(Node* node) { UNIMPLEMENTED(); } 2006 2007 void InstructionSelector::VisitFloat32x4NotEqual(Node* node) { 2008 UNIMPLEMENTED(); 2009 } 2010 2011 void InstructionSelector::VisitInt32x4FromFloat32x4(Node* node) { 2012 UNIMPLEMENTED(); 2013 } 2014 2015 void InstructionSelector::VisitUint32x4FromFloat32x4(Node* node) { 2016 UNIMPLEMENTED(); 2017 } 2018 2019 void InstructionSelector::VisitInt32x4Neg(Node* node) { UNIMPLEMENTED(); } 2020 2021 void InstructionSelector::VisitInt32x4ShiftLeftByScalar(Node* node) { 2022 UNIMPLEMENTED(); 2023 } 2024 2025 void InstructionSelector::VisitInt32x4ShiftRightByScalar(Node* node) { 2026 UNIMPLEMENTED(); 2027 } 2028 2029 void InstructionSelector::VisitInt32x4Mul(Node* node) { UNIMPLEMENTED(); } 2030 2031 void InstructionSelector::VisitInt32x4Max(Node* node) { UNIMPLEMENTED(); } 2032 2033 void InstructionSelector::VisitInt32x4Min(Node* node) { UNIMPLEMENTED(); } 2034 2035 void InstructionSelector::VisitInt32x4Equal(Node* node) { UNIMPLEMENTED(); } 2036 2037 void InstructionSelector::VisitInt32x4NotEqual(Node* node) { UNIMPLEMENTED(); } 2038 2039 void InstructionSelector::VisitInt32x4LessThan(Node* node) { UNIMPLEMENTED(); } 2040 2041 void InstructionSelector::VisitInt32x4LessThanOrEqual(Node* node) { 2042 UNIMPLEMENTED(); 2043 } 2044 2045 void InstructionSelector::VisitInt32x4GreaterThan(Node* node) { 2046 UNIMPLEMENTED(); 2047 } 2048 2049 void InstructionSelector::VisitInt32x4GreaterThanOrEqual(Node* node) { 2050 UNIMPLEMENTED(); 2051 } 2052 2053 void InstructionSelector::VisitUint32x4ShiftRightByScalar(Node* node) { 2054 UNIMPLEMENTED(); 2055 } 2056 2057 void InstructionSelector::VisitUint32x4Max(Node* node) { UNIMPLEMENTED(); } 2058 2059 void InstructionSelector::VisitUint32x4Min(Node* node) { UNIMPLEMENTED(); } 2060 2061 void InstructionSelector::VisitUint32x4GreaterThan(Node* node) { 2062 UNIMPLEMENTED(); 2063 } 2064 2065 void InstructionSelector::VisitUint32x4GreaterThanOrEqual(Node* node) { 2066 UNIMPLEMENTED(); 2067 } 2068 2069 void InstructionSelector::VisitCreateInt16x8(Node* node) { UNIMPLEMENTED(); } 2070 2071 void InstructionSelector::VisitInt16x8ExtractLane(Node* node) { 2072 UNIMPLEMENTED(); 2073 } 2074 2075 void InstructionSelector::VisitInt16x8ReplaceLane(Node* node) { 2076 UNIMPLEMENTED(); 2077 } 2078 2079 void InstructionSelector::VisitInt16x8Neg(Node* node) { UNIMPLEMENTED(); } 2080 2081 void InstructionSelector::VisitInt16x8ShiftLeftByScalar(Node* node) { 2082 UNIMPLEMENTED(); 2083 } 2084 2085 void InstructionSelector::VisitInt16x8ShiftRightByScalar(Node* node) { 2086 UNIMPLEMENTED(); 2087 } 2088 2089 void InstructionSelector::VisitInt16x8Add(Node* node) { UNIMPLEMENTED(); } 2090 2091 void InstructionSelector::VisitInt16x8AddSaturate(Node* node) { 2092 UNIMPLEMENTED(); 2093 } 2094 2095 void InstructionSelector::VisitInt16x8Sub(Node* node) { UNIMPLEMENTED(); } 2096 2097 void InstructionSelector::VisitInt16x8SubSaturate(Node* node) { 2098 UNIMPLEMENTED(); 2099 } 2100 2101 void InstructionSelector::VisitInt16x8Mul(Node* node) { UNIMPLEMENTED(); } 2102 2103 void InstructionSelector::VisitInt16x8Max(Node* node) { UNIMPLEMENTED(); } 2104 2105 void InstructionSelector::VisitInt16x8Min(Node* node) { UNIMPLEMENTED(); } 2106 2107 void InstructionSelector::VisitInt16x8Equal(Node* node) { UNIMPLEMENTED(); } 2108 2109 void InstructionSelector::VisitInt16x8NotEqual(Node* node) { UNIMPLEMENTED(); } 2110 2111 void InstructionSelector::VisitInt16x8LessThan(Node* node) { UNIMPLEMENTED(); } 2112 2113 void InstructionSelector::VisitInt16x8LessThanOrEqual(Node* node) { 2114 UNIMPLEMENTED(); 2115 } 2116 2117 void InstructionSelector::VisitInt16x8GreaterThan(Node* node) { 2118 UNIMPLEMENTED(); 2119 } 2120 2121 void InstructionSelector::VisitInt16x8GreaterThanOrEqual(Node* node) { 2122 UNIMPLEMENTED(); 2123 } 2124 2125 void InstructionSelector::VisitUint16x8ShiftRightByScalar(Node* node) { 2126 UNIMPLEMENTED(); 2127 } 2128 2129 void InstructionSelector::VisitUint16x8AddSaturate(Node* node) { 2130 UNIMPLEMENTED(); 2131 } 2132 2133 void InstructionSelector::VisitUint16x8SubSaturate(Node* node) { 2134 UNIMPLEMENTED(); 2135 } 2136 2137 void InstructionSelector::VisitUint16x8Max(Node* node) { UNIMPLEMENTED(); } 2138 2139 void InstructionSelector::VisitUint16x8Min(Node* node) { UNIMPLEMENTED(); } 2140 2141 void InstructionSelector::VisitUint16x8GreaterThan(Node* node) { 2142 UNIMPLEMENTED(); 2143 } 2144 2145 void InstructionSelector::VisitUint16x8GreaterThanOrEqual(Node* node) { 2146 UNIMPLEMENTED(); 2147 } 2148 2149 void InstructionSelector::VisitCreateInt8x16(Node* node) { UNIMPLEMENTED(); } 2150 2151 void InstructionSelector::VisitInt8x16ExtractLane(Node* node) { 2152 UNIMPLEMENTED(); 2153 } 2154 2155 void InstructionSelector::VisitInt8x16ReplaceLane(Node* node) { 2156 UNIMPLEMENTED(); 2157 } 2158 2159 void InstructionSelector::VisitInt8x16Neg(Node* node) { UNIMPLEMENTED(); } 2160 2161 void InstructionSelector::VisitInt8x16ShiftLeftByScalar(Node* node) { 2162 UNIMPLEMENTED(); 2163 } 2164 2165 void InstructionSelector::VisitInt8x16ShiftRightByScalar(Node* node) { 2166 UNIMPLEMENTED(); 2167 } 2168 2169 void InstructionSelector::VisitInt8x16Add(Node* node) { UNIMPLEMENTED(); } 2170 2171 void InstructionSelector::VisitInt8x16AddSaturate(Node* node) { 2172 UNIMPLEMENTED(); 2173 } 2174 2175 void InstructionSelector::VisitInt8x16Sub(Node* node) { UNIMPLEMENTED(); } 2176 2177 void InstructionSelector::VisitInt8x16SubSaturate(Node* node) { 2178 UNIMPLEMENTED(); 2179 } 2180 2181 void InstructionSelector::VisitInt8x16Mul(Node* node) { UNIMPLEMENTED(); } 2182 2183 void InstructionSelector::VisitInt8x16Max(Node* node) { UNIMPLEMENTED(); } 2184 2185 void InstructionSelector::VisitInt8x16Min(Node* node) { UNIMPLEMENTED(); } 2186 2187 void InstructionSelector::VisitInt8x16Equal(Node* node) { UNIMPLEMENTED(); } 2188 2189 void InstructionSelector::VisitInt8x16NotEqual(Node* node) { UNIMPLEMENTED(); } 2190 2191 void InstructionSelector::VisitInt8x16LessThan(Node* node) { UNIMPLEMENTED(); } 2192 2193 void InstructionSelector::VisitInt8x16LessThanOrEqual(Node* node) { 2194 UNIMPLEMENTED(); 2195 } 2196 2197 void InstructionSelector::VisitInt8x16GreaterThan(Node* node) { 2198 UNIMPLEMENTED(); 2199 } 2200 2201 void InstructionSelector::VisitInt8x16GreaterThanOrEqual(Node* node) { 2202 UNIMPLEMENTED(); 2203 } 2204 2205 void InstructionSelector::VisitUint8x16ShiftRightByScalar(Node* node) { 2206 UNIMPLEMENTED(); 2207 } 2208 2209 void InstructionSelector::VisitUint8x16AddSaturate(Node* node) { 2210 UNIMPLEMENTED(); 2211 } 2212 2213 void InstructionSelector::VisitUint8x16SubSaturate(Node* node) { 2214 UNIMPLEMENTED(); 2215 } 2216 2217 void InstructionSelector::VisitUint8x16Max(Node* node) { UNIMPLEMENTED(); } 2218 2219 void InstructionSelector::VisitUint8x16Min(Node* node) { UNIMPLEMENTED(); } 2220 2221 void InstructionSelector::VisitUint8x16GreaterThan(Node* node) { 2222 UNIMPLEMENTED(); 2223 } 2224 2225 void InstructionSelector::VisitUint8x16GreaterThanOrEqual(Node* node) { 2226 UNIMPLEMENTED(); 2227 } 2228 2229 void InstructionSelector::VisitSimd128And(Node* node) { UNIMPLEMENTED(); } 2230 2231 void InstructionSelector::VisitSimd128Or(Node* node) { UNIMPLEMENTED(); } 2232 2233 void InstructionSelector::VisitSimd128Xor(Node* node) { UNIMPLEMENTED(); } 2234 2235 void InstructionSelector::VisitSimd128Not(Node* node) { UNIMPLEMENTED(); } 2236 2237 void InstructionSelector::VisitSimd32x4Select(Node* node) { UNIMPLEMENTED(); } 2238 2239 void InstructionSelector::VisitSimd16x8Select(Node* node) { UNIMPLEMENTED(); } 2240 2241 void InstructionSelector::VisitSimd8x16Select(Node* node) { UNIMPLEMENTED(); } 2242 #endif // !V8_TARGET_ARCH_ARM 2243 2244 void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); } 2245 2246 void InstructionSelector::VisitParameter(Node* node) { 2247 OperandGenerator g(this); 2248 int index = ParameterIndexOf(node->op()); 2249 InstructionOperand op = 2250 linkage()->ParameterHasSecondaryLocation(index) 2251 ? g.DefineAsDualLocation( 2252 node, linkage()->GetParameterLocation(index), 2253 linkage()->GetParameterSecondaryLocation(index)) 2254 : g.DefineAsLocation(node, linkage()->GetParameterLocation(index)); 2255 2256 Emit(kArchNop, op); 2257 } 2258 2259 namespace { 2260 LinkageLocation ExceptionLocation() { 2261 return LinkageLocation::ForRegister(kReturnRegister0.code(), 2262 MachineType::IntPtr()); 2263 } 2264 } 2265 2266 void InstructionSelector::VisitIfException(Node* node) { 2267 OperandGenerator g(this); 2268 DCHECK_EQ(IrOpcode::kCall, node->InputAt(1)->opcode()); 2269 Emit(kArchNop, g.DefineAsLocation(node, ExceptionLocation())); 2270 } 2271 2272 2273 void InstructionSelector::VisitOsrValue(Node* node) { 2274 OperandGenerator g(this); 2275 int index = OsrValueIndexOf(node->op()); 2276 Emit(kArchNop, 2277 g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index))); 2278 } 2279 2280 2281 void InstructionSelector::VisitPhi(Node* node) { 2282 const int input_count = node->op()->ValueInputCount(); 2283 PhiInstruction* phi = new (instruction_zone()) 2284 PhiInstruction(instruction_zone(), GetVirtualRegister(node), 2285 static_cast<size_t>(input_count)); 2286 sequence() 2287 ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number())) 2288 ->AddPhi(phi); 2289 for (int i = 0; i < input_count; ++i) { 2290 Node* const input = node->InputAt(i); 2291 MarkAsUsed(input); 2292 phi->SetInput(static_cast<size_t>(i), GetVirtualRegister(input)); 2293 } 2294 } 2295 2296 2297 void InstructionSelector::VisitProjection(Node* node) { 2298 OperandGenerator g(this); 2299 Node* value = node->InputAt(0); 2300 switch (value->opcode()) { 2301 case IrOpcode::kInt32AddWithOverflow: 2302 case IrOpcode::kInt32SubWithOverflow: 2303 case IrOpcode::kInt32MulWithOverflow: 2304 case IrOpcode::kInt64AddWithOverflow: 2305 case IrOpcode::kInt64SubWithOverflow: 2306 case IrOpcode::kTryTruncateFloat32ToInt64: 2307 case IrOpcode::kTryTruncateFloat64ToInt64: 2308 case IrOpcode::kTryTruncateFloat32ToUint64: 2309 case IrOpcode::kTryTruncateFloat64ToUint64: 2310 case IrOpcode::kInt32PairAdd: 2311 case IrOpcode::kInt32PairSub: 2312 case IrOpcode::kInt32PairMul: 2313 case IrOpcode::kWord32PairShl: 2314 case IrOpcode::kWord32PairShr: 2315 case IrOpcode::kWord32PairSar: 2316 if (ProjectionIndexOf(node->op()) == 0u) { 2317 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); 2318 } else { 2319 DCHECK(ProjectionIndexOf(node->op()) == 1u); 2320 MarkAsUsed(value); 2321 } 2322 break; 2323 default: 2324 break; 2325 } 2326 } 2327 2328 2329 void InstructionSelector::VisitConstant(Node* node) { 2330 // We must emit a NOP here because every live range needs a defining 2331 // instruction in the register allocator. 2332 OperandGenerator g(this); 2333 Emit(kArchNop, g.DefineAsConstant(node)); 2334 } 2335 2336 2337 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { 2338 OperandGenerator g(this); 2339 const CallDescriptor* descriptor = CallDescriptorOf(node->op()); 2340 2341 FrameStateDescriptor* frame_state_descriptor = nullptr; 2342 if (descriptor->NeedsFrameState()) { 2343 frame_state_descriptor = GetFrameStateDescriptor( 2344 node->InputAt(static_cast<int>(descriptor->InputCount()))); 2345 } 2346 2347 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); 2348 2349 // Compute InstructionOperands for inputs and outputs. 2350 // TODO(turbofan): on some architectures it's probably better to use 2351 // the code object in a register if there are multiple uses of it. 2352 // Improve constant pool and the heuristics in the register allocator 2353 // for where to emit constants. 2354 CallBufferFlags call_buffer_flags(kCallCodeImmediate | kCallAddressImmediate); 2355 InitializeCallBuffer(node, &buffer, call_buffer_flags); 2356 2357 EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node); 2358 2359 // Pass label of exception handler block. 2360 CallDescriptor::Flags flags = descriptor->flags(); 2361 if (handler) { 2362 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); 2363 flags |= CallDescriptor::kHasExceptionHandler; 2364 buffer.instruction_args.push_back(g.Label(handler)); 2365 } 2366 2367 bool from_native_stack = linkage()->GetIncomingDescriptor()->UseNativeStack(); 2368 bool to_native_stack = descriptor->UseNativeStack(); 2369 if (from_native_stack != to_native_stack) { 2370 // (arm64 only) Mismatch in the use of stack pointers. One or the other 2371 // has to be restored manually by the code generator. 2372 flags |= to_native_stack ? CallDescriptor::kRestoreJSSP 2373 : CallDescriptor::kRestoreCSP; 2374 } 2375 2376 // Select the appropriate opcode based on the call type. 2377 InstructionCode opcode = kArchNop; 2378 switch (descriptor->kind()) { 2379 case CallDescriptor::kCallAddress: 2380 opcode = 2381 kArchCallCFunction | 2382 MiscField::encode(static_cast<int>(descriptor->ParameterCount())); 2383 break; 2384 case CallDescriptor::kCallCodeObject: 2385 opcode = kArchCallCodeObject | MiscField::encode(flags); 2386 break; 2387 case CallDescriptor::kCallJSFunction: 2388 opcode = kArchCallJSFunction | MiscField::encode(flags); 2389 break; 2390 } 2391 2392 // Emit the call instruction. 2393 size_t const output_count = buffer.outputs.size(); 2394 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; 2395 Instruction* call_instr = 2396 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), 2397 &buffer.instruction_args.front()); 2398 if (instruction_selection_failed()) return; 2399 call_instr->MarkAsCall(); 2400 } 2401 2402 2403 void InstructionSelector::VisitTailCall(Node* node) { 2404 OperandGenerator g(this); 2405 CallDescriptor const* descriptor = CallDescriptorOf(node->op()); 2406 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); 2407 2408 CallDescriptor* caller = linkage()->GetIncomingDescriptor(); 2409 DCHECK(caller->CanTailCall(node)); 2410 const CallDescriptor* callee = CallDescriptorOf(node->op()); 2411 int stack_param_delta = callee->GetStackParameterDelta(caller); 2412 CallBuffer buffer(zone(), descriptor, nullptr); 2413 2414 // Compute InstructionOperands for inputs and outputs. 2415 CallBufferFlags flags(kCallCodeImmediate | kCallTail); 2416 if (IsTailCallAddressImmediate()) { 2417 flags |= kCallAddressImmediate; 2418 } 2419 InitializeCallBuffer(node, &buffer, flags, stack_param_delta); 2420 2421 // Select the appropriate opcode based on the call type. 2422 InstructionCode opcode; 2423 InstructionOperandVector temps(zone()); 2424 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { 2425 switch (descriptor->kind()) { 2426 case CallDescriptor::kCallCodeObject: 2427 opcode = kArchTailCallCodeObjectFromJSFunction; 2428 break; 2429 case CallDescriptor::kCallJSFunction: 2430 opcode = kArchTailCallJSFunctionFromJSFunction; 2431 break; 2432 default: 2433 UNREACHABLE(); 2434 return; 2435 } 2436 int temps_count = GetTempsCountForTailCallFromJSFunction(); 2437 for (int i = 0; i < temps_count; i++) { 2438 temps.push_back(g.TempRegister()); 2439 } 2440 } else { 2441 switch (descriptor->kind()) { 2442 case CallDescriptor::kCallCodeObject: 2443 opcode = kArchTailCallCodeObject; 2444 break; 2445 case CallDescriptor::kCallAddress: 2446 opcode = kArchTailCallAddress; 2447 break; 2448 default: 2449 UNREACHABLE(); 2450 return; 2451 } 2452 } 2453 opcode |= MiscField::encode(descriptor->flags()); 2454 2455 Emit(kArchPrepareTailCall, g.NoOutput()); 2456 2457 int first_unused_stack_slot = 2458 (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0) + 2459 stack_param_delta; 2460 buffer.instruction_args.push_back(g.TempImmediate(first_unused_stack_slot)); 2461 2462 // Emit the tailcall instruction. 2463 Emit(opcode, 0, nullptr, buffer.instruction_args.size(), 2464 &buffer.instruction_args.front(), temps.size(), 2465 temps.empty() ? nullptr : &temps.front()); 2466 } 2467 2468 2469 void InstructionSelector::VisitGoto(BasicBlock* target) { 2470 // jump to the next block. 2471 OperandGenerator g(this); 2472 Emit(kArchJmp, g.NoOutput(), g.Label(target)); 2473 } 2474 2475 void InstructionSelector::VisitReturn(Node* ret) { 2476 OperandGenerator g(this); 2477 const int input_count = linkage()->GetIncomingDescriptor()->ReturnCount() == 0 2478 ? 1 2479 : ret->op()->ValueInputCount(); 2480 DCHECK_GE(input_count, 1); 2481 auto value_locations = zone()->NewArray<InstructionOperand>(input_count); 2482 Node* pop_count = ret->InputAt(0); 2483 value_locations[0] = (pop_count->opcode() == IrOpcode::kInt32Constant || 2484 pop_count->opcode() == IrOpcode::kInt64Constant) 2485 ? g.UseImmediate(pop_count) 2486 : g.UseRegister(pop_count); 2487 for (int i = 1; i < input_count; ++i) { 2488 value_locations[i] = 2489 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i - 1)); 2490 } 2491 Emit(kArchRet, 0, nullptr, input_count, value_locations); 2492 } 2493 2494 Instruction* InstructionSelector::EmitDeoptimize( 2495 InstructionCode opcode, InstructionOperand output, InstructionOperand a, 2496 DeoptimizeKind kind, DeoptimizeReason reason, Node* frame_state) { 2497 size_t output_count = output.IsInvalid() ? 0 : 1; 2498 InstructionOperand inputs[] = {a}; 2499 size_t input_count = arraysize(inputs); 2500 return EmitDeoptimize(opcode, output_count, &output, input_count, inputs, 2501 kind, reason, frame_state); 2502 } 2503 2504 Instruction* InstructionSelector::EmitDeoptimize( 2505 InstructionCode opcode, InstructionOperand output, InstructionOperand a, 2506 InstructionOperand b, DeoptimizeKind kind, DeoptimizeReason reason, 2507 Node* frame_state) { 2508 size_t output_count = output.IsInvalid() ? 0 : 1; 2509 InstructionOperand inputs[] = {a, b}; 2510 size_t input_count = arraysize(inputs); 2511 return EmitDeoptimize(opcode, output_count, &output, input_count, inputs, 2512 kind, reason, frame_state); 2513 } 2514 2515 Instruction* InstructionSelector::EmitDeoptimize( 2516 InstructionCode opcode, size_t output_count, InstructionOperand* outputs, 2517 size_t input_count, InstructionOperand* inputs, DeoptimizeKind kind, 2518 DeoptimizeReason reason, Node* frame_state) { 2519 OperandGenerator g(this); 2520 FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state); 2521 InstructionOperandVector args(instruction_zone()); 2522 args.reserve(input_count + 1 + descriptor->GetTotalSize()); 2523 for (size_t i = 0; i < input_count; ++i) { 2524 args.push_back(inputs[i]); 2525 } 2526 opcode |= MiscField::encode(static_cast<int>(input_count)); 2527 int const state_id = 2528 sequence()->AddDeoptimizationEntry(descriptor, kind, reason); 2529 args.push_back(g.TempImmediate(state_id)); 2530 StateObjectDeduplicator deduplicator(instruction_zone()); 2531 AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator, 2532 &args, FrameStateInputKind::kAny, 2533 instruction_zone()); 2534 return Emit(opcode, output_count, outputs, args.size(), &args.front(), 0, 2535 nullptr); 2536 } 2537 2538 void InstructionSelector::EmitIdentity(Node* node) { 2539 OperandGenerator g(this); 2540 MarkAsUsed(node->InputAt(0)); 2541 SetRename(node, node->InputAt(0)); 2542 } 2543 2544 void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, 2545 DeoptimizeReason reason, 2546 Node* value) { 2547 EmitDeoptimize(kArchDeoptimize, 0, nullptr, 0, nullptr, kind, reason, value); 2548 } 2549 2550 2551 void InstructionSelector::VisitThrow(Node* value) { 2552 OperandGenerator g(this); 2553 Emit(kArchThrowTerminator, g.NoOutput()); 2554 } 2555 2556 void InstructionSelector::VisitDebugBreak(Node* node) { 2557 OperandGenerator g(this); 2558 Emit(kArchDebugBreak, g.NoOutput()); 2559 } 2560 2561 void InstructionSelector::VisitComment(Node* node) { 2562 OperandGenerator g(this); 2563 InstructionOperand operand(g.UseImmediate(node)); 2564 Emit(kArchComment, 0, nullptr, 1, &operand); 2565 } 2566 2567 void InstructionSelector::VisitUnsafePointerAdd(Node* node) { 2568 #if V8_TARGET_ARCH_64_BIT 2569 VisitInt64Add(node); 2570 #else // V8_TARGET_ARCH_64_BIT 2571 VisitInt32Add(node); 2572 #endif // V8_TARGET_ARCH_64_BIT 2573 } 2574 2575 void InstructionSelector::VisitRetain(Node* node) { 2576 OperandGenerator g(this); 2577 Emit(kArchNop, g.NoOutput(), g.UseAny(node->InputAt(0))); 2578 } 2579 2580 bool InstructionSelector::CanProduceSignalingNaN(Node* node) { 2581 // TODO(jarin) Improve the heuristic here. 2582 if (node->opcode() == IrOpcode::kFloat64Add || 2583 node->opcode() == IrOpcode::kFloat64Sub || 2584 node->opcode() == IrOpcode::kFloat64Mul) { 2585 return false; 2586 } 2587 return true; 2588 } 2589 2590 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( 2591 Node* state) { 2592 DCHECK(state->opcode() == IrOpcode::kFrameState); 2593 DCHECK_EQ(kFrameStateInputCount, state->InputCount()); 2594 FrameStateInfo state_info = OpParameter<FrameStateInfo>(state); 2595 2596 int parameters = static_cast<int>( 2597 StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size()); 2598 int locals = static_cast<int>( 2599 StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size()); 2600 int stack = static_cast<int>( 2601 StateValuesAccess(state->InputAt(kFrameStateStackInput)).size()); 2602 2603 DCHECK_EQ(parameters, state_info.parameter_count()); 2604 DCHECK_EQ(locals, state_info.local_count()); 2605 2606 FrameStateDescriptor* outer_state = nullptr; 2607 Node* outer_node = state->InputAt(kFrameStateOuterStateInput); 2608 if (outer_node->opcode() == IrOpcode::kFrameState) { 2609 outer_state = GetFrameStateDescriptor(outer_node); 2610 } 2611 2612 return new (instruction_zone()) FrameStateDescriptor( 2613 instruction_zone(), state_info.type(), state_info.bailout_id(), 2614 state_info.state_combine(), parameters, locals, stack, 2615 state_info.shared_info(), outer_state); 2616 } 2617 2618 2619 } // namespace compiler 2620 } // namespace internal 2621 } // namespace v8 2622