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 18 namespace v8 { 19 namespace internal { 20 namespace compiler { 21 22 InstructionSelector::InstructionSelector( 23 Zone* zone, size_t node_count, Linkage* linkage, 24 InstructionSequence* sequence, Schedule* schedule, 25 SourcePositionTable* source_positions, Frame* frame, 26 SourcePositionMode source_position_mode, Features features, 27 EnableScheduling enable_scheduling, 28 EnableSerialization enable_serialization) 29 : zone_(zone), 30 linkage_(linkage), 31 sequence_(sequence), 32 source_positions_(source_positions), 33 source_position_mode_(source_position_mode), 34 features_(features), 35 schedule_(schedule), 36 current_block_(nullptr), 37 instructions_(zone), 38 defined_(node_count, false, zone), 39 used_(node_count, false, zone), 40 effect_level_(node_count, 0, zone), 41 virtual_registers_(node_count, 42 InstructionOperand::kInvalidVirtualRegister, zone), 43 virtual_register_rename_(zone), 44 scheduler_(nullptr), 45 enable_scheduling_(enable_scheduling), 46 enable_serialization_(enable_serialization), 47 frame_(frame), 48 instruction_selection_failed_(false) { 49 instructions_.reserve(node_count); 50 } 51 52 bool InstructionSelector::SelectInstructions() { 53 // Mark the inputs of all phis in loop headers as used. 54 BasicBlockVector* blocks = schedule()->rpo_order(); 55 for (auto const block : *blocks) { 56 if (!block->IsLoopHeader()) continue; 57 DCHECK_LE(2u, block->PredecessorCount()); 58 for (Node* const phi : *block) { 59 if (phi->opcode() != IrOpcode::kPhi) continue; 60 61 // Mark all inputs as used. 62 for (Node* const input : phi->inputs()) { 63 MarkAsUsed(input); 64 } 65 } 66 } 67 68 // Visit each basic block in post order. 69 for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) { 70 VisitBlock(*i); 71 if (instruction_selection_failed()) return false; 72 } 73 74 // Schedule the selected instructions. 75 if (UseInstructionScheduling()) { 76 scheduler_ = new (zone()) InstructionScheduler(zone(), sequence()); 77 } 78 79 for (auto const block : *blocks) { 80 InstructionBlock* instruction_block = 81 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); 82 for (size_t i = 0; i < instruction_block->phis().size(); i++) { 83 UpdateRenamesInPhi(instruction_block->PhiAt(i)); 84 } 85 size_t end = instruction_block->code_end(); 86 size_t start = instruction_block->code_start(); 87 DCHECK_LE(end, start); 88 StartBlock(RpoNumber::FromInt(block->rpo_number())); 89 while (start-- > end) { 90 UpdateRenames(instructions_[start]); 91 AddInstruction(instructions_[start]); 92 } 93 EndBlock(RpoNumber::FromInt(block->rpo_number())); 94 } 95 #if DEBUG 96 sequence()->ValidateSSA(); 97 #endif 98 return true; 99 } 100 101 void InstructionSelector::StartBlock(RpoNumber rpo) { 102 if (UseInstructionScheduling()) { 103 DCHECK_NOT_NULL(scheduler_); 104 scheduler_->StartBlock(rpo); 105 } else { 106 sequence()->StartBlock(rpo); 107 } 108 } 109 110 111 void InstructionSelector::EndBlock(RpoNumber rpo) { 112 if (UseInstructionScheduling()) { 113 DCHECK_NOT_NULL(scheduler_); 114 scheduler_->EndBlock(rpo); 115 } else { 116 sequence()->EndBlock(rpo); 117 } 118 } 119 120 121 void InstructionSelector::AddInstruction(Instruction* instr) { 122 if (UseInstructionScheduling()) { 123 DCHECK_NOT_NULL(scheduler_); 124 scheduler_->AddInstruction(instr); 125 } else { 126 sequence()->AddInstruction(instr); 127 } 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 418 namespace { 419 420 enum class FrameStateInputKind { kAny, kStackSlot }; 421 422 InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, 423 FrameStateInputKind kind, 424 MachineRepresentation rep) { 425 if (rep == MachineRepresentation::kNone) { 426 return g->TempImmediate(FrameStateDescriptor::kImpossibleValue); 427 } 428 429 switch (input->opcode()) { 430 case IrOpcode::kInt32Constant: 431 case IrOpcode::kInt64Constant: 432 case IrOpcode::kNumberConstant: 433 case IrOpcode::kFloat32Constant: 434 case IrOpcode::kFloat64Constant: 435 case IrOpcode::kHeapConstant: 436 return g->UseImmediate(input); 437 case IrOpcode::kObjectState: 438 case IrOpcode::kTypedObjectState: 439 UNREACHABLE(); 440 break; 441 default: 442 switch (kind) { 443 case FrameStateInputKind::kStackSlot: 444 return g->UseUniqueSlot(input); 445 case FrameStateInputKind::kAny: 446 // Currently deopts "wrap" other operations, so the deopt's inputs 447 // are potentially needed untill the end of the deoptimising code. 448 return g->UseAnyAtEnd(input); 449 } 450 } 451 UNREACHABLE(); 452 return InstructionOperand(); 453 } 454 455 456 class StateObjectDeduplicator { 457 public: 458 explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {} 459 static const size_t kNotDuplicated = SIZE_MAX; 460 461 size_t GetObjectId(Node* node) { 462 for (size_t i = 0; i < objects_.size(); ++i) { 463 if (objects_[i] == node) { 464 return i; 465 } 466 } 467 return kNotDuplicated; 468 } 469 470 size_t InsertObject(Node* node) { 471 size_t id = objects_.size(); 472 objects_.push_back(node); 473 return id; 474 } 475 476 private: 477 ZoneVector<Node*> objects_; 478 }; 479 480 481 // Returns the number of instruction operands added to inputs. 482 size_t AddOperandToStateValueDescriptor(StateValueDescriptor* descriptor, 483 InstructionOperandVector* inputs, 484 OperandGenerator* g, 485 StateObjectDeduplicator* deduplicator, 486 Node* input, MachineType type, 487 FrameStateInputKind kind, Zone* zone) { 488 switch (input->opcode()) { 489 case IrOpcode::kObjectState: { 490 UNREACHABLE(); 491 return 0; 492 } 493 case IrOpcode::kTypedObjectState: { 494 size_t id = deduplicator->GetObjectId(input); 495 if (id == StateObjectDeduplicator::kNotDuplicated) { 496 size_t entries = 0; 497 id = deduplicator->InsertObject(input); 498 descriptor->fields().push_back( 499 StateValueDescriptor::Recursive(zone, id)); 500 StateValueDescriptor* new_desc = &descriptor->fields().back(); 501 int const input_count = input->op()->ValueInputCount(); 502 ZoneVector<MachineType> const* types = MachineTypesOf(input->op()); 503 for (int i = 0; i < input_count; ++i) { 504 entries += AddOperandToStateValueDescriptor( 505 new_desc, inputs, g, deduplicator, input->InputAt(i), 506 types->at(i), kind, zone); 507 } 508 return entries; 509 } else { 510 // Crankshaft counts duplicate objects for the running id, so we have 511 // to push the input again. 512 deduplicator->InsertObject(input); 513 descriptor->fields().push_back( 514 StateValueDescriptor::Duplicate(zone, id)); 515 return 0; 516 } 517 } 518 default: { 519 inputs->push_back(OperandForDeopt(g, input, kind, type.representation())); 520 descriptor->fields().push_back(StateValueDescriptor::Plain(zone, type)); 521 return 1; 522 } 523 } 524 } 525 526 527 // Returns the number of instruction operands added to inputs. 528 size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor, 529 Node* state, OperandGenerator* g, 530 StateObjectDeduplicator* deduplicator, 531 InstructionOperandVector* inputs, 532 FrameStateInputKind kind, Zone* zone) { 533 DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode()); 534 535 size_t entries = 0; 536 size_t initial_size = inputs->size(); 537 USE(initial_size); // initial_size is only used for debug. 538 539 if (descriptor->outer_state()) { 540 entries += AddInputsToFrameStateDescriptor( 541 descriptor->outer_state(), state->InputAt(kFrameStateOuterStateInput), 542 g, deduplicator, inputs, kind, zone); 543 } 544 545 Node* parameters = state->InputAt(kFrameStateParametersInput); 546 Node* locals = state->InputAt(kFrameStateLocalsInput); 547 Node* stack = state->InputAt(kFrameStateStackInput); 548 Node* context = state->InputAt(kFrameStateContextInput); 549 Node* function = state->InputAt(kFrameStateFunctionInput); 550 551 DCHECK_EQ(descriptor->parameters_count(), 552 StateValuesAccess(parameters).size()); 553 DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size()); 554 DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size()); 555 556 StateValueDescriptor* values_descriptor = 557 descriptor->GetStateValueDescriptor(); 558 entries += AddOperandToStateValueDescriptor( 559 values_descriptor, inputs, g, deduplicator, function, 560 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone); 561 for (StateValuesAccess::TypedNode input_node : 562 StateValuesAccess(parameters)) { 563 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g, 564 deduplicator, input_node.node, 565 input_node.type, kind, zone); 566 } 567 if (descriptor->HasContext()) { 568 entries += AddOperandToStateValueDescriptor( 569 values_descriptor, inputs, g, deduplicator, context, 570 MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone); 571 } 572 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) { 573 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g, 574 deduplicator, input_node.node, 575 input_node.type, kind, zone); 576 } 577 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) { 578 entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g, 579 deduplicator, input_node.node, 580 input_node.type, kind, zone); 581 } 582 DCHECK_EQ(initial_size + entries, inputs->size()); 583 return entries; 584 } 585 586 } // namespace 587 588 589 // An internal helper class for generating the operands to calls. 590 // TODO(bmeurer): Get rid of the CallBuffer business and make 591 // InstructionSelector::VisitCall platform independent instead. 592 struct CallBuffer { 593 CallBuffer(Zone* zone, const CallDescriptor* descriptor, 594 FrameStateDescriptor* frame_state) 595 : descriptor(descriptor), 596 frame_state_descriptor(frame_state), 597 output_nodes(zone), 598 outputs(zone), 599 instruction_args(zone), 600 pushed_nodes(zone) { 601 output_nodes.reserve(descriptor->ReturnCount()); 602 outputs.reserve(descriptor->ReturnCount()); 603 pushed_nodes.reserve(input_count()); 604 instruction_args.reserve(input_count() + frame_state_value_count()); 605 } 606 607 608 const CallDescriptor* descriptor; 609 FrameStateDescriptor* frame_state_descriptor; 610 NodeVector output_nodes; 611 InstructionOperandVector outputs; 612 InstructionOperandVector instruction_args; 613 ZoneVector<PushParameter> pushed_nodes; 614 615 size_t input_count() const { return descriptor->InputCount(); } 616 617 size_t frame_state_count() const { return descriptor->FrameStateCount(); } 618 619 size_t frame_state_value_count() const { 620 return (frame_state_descriptor == nullptr) 621 ? 0 622 : (frame_state_descriptor->GetTotalSize() + 623 1); // Include deopt id. 624 } 625 }; 626 627 628 // TODO(bmeurer): Get rid of the CallBuffer business and make 629 // InstructionSelector::VisitCall platform independent instead. 630 void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, 631 CallBufferFlags flags, 632 int stack_param_delta) { 633 OperandGenerator g(this); 634 DCHECK_LE(call->op()->ValueOutputCount(), 635 static_cast<int>(buffer->descriptor->ReturnCount())); 636 DCHECK_EQ( 637 call->op()->ValueInputCount(), 638 static_cast<int>(buffer->input_count() + buffer->frame_state_count())); 639 640 if (buffer->descriptor->ReturnCount() > 0) { 641 // Collect the projections that represent multiple outputs from this call. 642 if (buffer->descriptor->ReturnCount() == 1) { 643 buffer->output_nodes.push_back(call); 644 } else { 645 buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), nullptr); 646 for (auto use : call->uses()) { 647 if (use->opcode() != IrOpcode::kProjection) continue; 648 size_t const index = ProjectionIndexOf(use->op()); 649 DCHECK_LT(index, buffer->output_nodes.size()); 650 DCHECK(!buffer->output_nodes[index]); 651 buffer->output_nodes[index] = use; 652 } 653 } 654 655 // Filter out the outputs that aren't live because no projection uses them. 656 size_t outputs_needed_by_framestate = 657 buffer->frame_state_descriptor == nullptr 658 ? 0 659 : buffer->frame_state_descriptor->state_combine() 660 .ConsumedOutputCount(); 661 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { 662 bool output_is_live = buffer->output_nodes[i] != nullptr || 663 i < outputs_needed_by_framestate; 664 if (output_is_live) { 665 MachineRepresentation rep = 666 buffer->descriptor->GetReturnType(static_cast<int>(i)) 667 .representation(); 668 LinkageLocation location = 669 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); 670 671 Node* output = buffer->output_nodes[i]; 672 InstructionOperand op = output == nullptr 673 ? g.TempLocation(location) 674 : g.DefineAsLocation(output, location); 675 MarkAsRepresentation(rep, op); 676 677 buffer->outputs.push_back(op); 678 } 679 } 680 } 681 682 // The first argument is always the callee code. 683 Node* callee = call->InputAt(0); 684 bool call_code_immediate = (flags & kCallCodeImmediate) != 0; 685 bool call_address_immediate = (flags & kCallAddressImmediate) != 0; 686 switch (buffer->descriptor->kind()) { 687 case CallDescriptor::kCallCodeObject: 688 buffer->instruction_args.push_back( 689 (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant) 690 ? g.UseImmediate(callee) 691 : g.UseRegister(callee)); 692 break; 693 case CallDescriptor::kCallAddress: 694 buffer->instruction_args.push_back( 695 (call_address_immediate && 696 callee->opcode() == IrOpcode::kExternalConstant) 697 ? g.UseImmediate(callee) 698 : g.UseRegister(callee)); 699 break; 700 case CallDescriptor::kCallJSFunction: 701 buffer->instruction_args.push_back( 702 g.UseLocation(callee, buffer->descriptor->GetInputLocation(0))); 703 break; 704 } 705 DCHECK_EQ(1u, buffer->instruction_args.size()); 706 707 // If the call needs a frame state, we insert the state information as 708 // follows (n is the number of value inputs to the frame state): 709 // arg 1 : deoptimization id. 710 // arg 2 - arg (n + 1) : value inputs to the frame state. 711 size_t frame_state_entries = 0; 712 USE(frame_state_entries); // frame_state_entries is only used for debug. 713 if (buffer->frame_state_descriptor != nullptr) { 714 Node* frame_state = 715 call->InputAt(static_cast<int>(buffer->descriptor->InputCount())); 716 717 // If it was a syntactic tail call we need to drop the current frame and 718 // all the frames on top of it that are either an arguments adaptor frame 719 // or a tail caller frame. 720 if (buffer->descriptor->SupportsTailCalls()) { 721 frame_state = NodeProperties::GetFrameStateInput(frame_state); 722 buffer->frame_state_descriptor = 723 buffer->frame_state_descriptor->outer_state(); 724 while (buffer->frame_state_descriptor != nullptr && 725 (buffer->frame_state_descriptor->type() == 726 FrameStateType::kArgumentsAdaptor || 727 buffer->frame_state_descriptor->type() == 728 FrameStateType::kTailCallerFunction)) { 729 frame_state = NodeProperties::GetFrameStateInput(frame_state); 730 buffer->frame_state_descriptor = 731 buffer->frame_state_descriptor->outer_state(); 732 } 733 } 734 735 int const state_id = sequence()->AddDeoptimizationEntry( 736 buffer->frame_state_descriptor, DeoptimizeReason::kNoReason); 737 buffer->instruction_args.push_back(g.TempImmediate(state_id)); 738 739 StateObjectDeduplicator deduplicator(instruction_zone()); 740 741 frame_state_entries = 742 1 + AddInputsToFrameStateDescriptor( 743 buffer->frame_state_descriptor, frame_state, &g, &deduplicator, 744 &buffer->instruction_args, FrameStateInputKind::kStackSlot, 745 instruction_zone()); 746 747 DCHECK_EQ(1 + frame_state_entries, buffer->instruction_args.size()); 748 } 749 750 size_t input_count = static_cast<size_t>(buffer->input_count()); 751 752 // Split the arguments into pushed_nodes and instruction_args. Pushed 753 // arguments require an explicit push instruction before the call and do 754 // not appear as arguments to the call. Everything else ends up 755 // as an InstructionOperand argument to the call. 756 auto iter(call->inputs().begin()); 757 size_t pushed_count = 0; 758 bool call_tail = (flags & kCallTail) != 0; 759 for (size_t index = 0; index < input_count; ++iter, ++index) { 760 DCHECK(iter != call->inputs().end()); 761 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); 762 if (index == 0) continue; // The first argument (callee) is already done. 763 764 LinkageLocation location = buffer->descriptor->GetInputLocation(index); 765 if (call_tail) { 766 location = LinkageLocation::ConvertToTailCallerLocation( 767 location, stack_param_delta); 768 } 769 InstructionOperand op = g.UseLocation(*iter, location); 770 if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) { 771 int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1; 772 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { 773 buffer->pushed_nodes.resize(stack_index + 1); 774 } 775 PushParameter parameter(*iter, buffer->descriptor->GetInputType(index)); 776 buffer->pushed_nodes[stack_index] = parameter; 777 pushed_count++; 778 } else { 779 buffer->instruction_args.push_back(op); 780 } 781 } 782 DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count - 783 frame_state_entries); 784 if (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK && call_tail && 785 stack_param_delta != 0) { 786 // For tail calls that change the size of their parameter list and keep 787 // their return address on the stack, move the return address to just above 788 // the parameters. 789 LinkageLocation saved_return_location = 790 LinkageLocation::ForSavedCallerReturnAddress(); 791 InstructionOperand return_address = 792 g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation( 793 saved_return_location, stack_param_delta), 794 saved_return_location); 795 buffer->instruction_args.push_back(return_address); 796 } 797 } 798 799 void InstructionSelector::VisitBlock(BasicBlock* block) { 800 DCHECK(!current_block_); 801 current_block_ = block; 802 int current_block_end = static_cast<int>(instructions_.size()); 803 804 int effect_level = 0; 805 for (Node* const node : *block) { 806 if (node->opcode() == IrOpcode::kStore || 807 node->opcode() == IrOpcode::kUnalignedStore || 808 node->opcode() == IrOpcode::kCheckedStore || 809 node->opcode() == IrOpcode::kCall) { 810 ++effect_level; 811 } 812 SetEffectLevel(node, effect_level); 813 } 814 815 // We visit the control first, then the nodes in the block, so the block's 816 // control input should be on the same effect level as the last node. 817 if (block->control_input() != nullptr) { 818 SetEffectLevel(block->control_input(), effect_level); 819 } 820 821 // Generate code for the block control "top down", but schedule the code 822 // "bottom up". 823 VisitControl(block); 824 std::reverse(instructions_.begin() + current_block_end, instructions_.end()); 825 826 // Visit code in reverse control flow order, because architecture-specific 827 // matching may cover more than one node at a time. 828 for (auto node : base::Reversed(*block)) { 829 // Skip nodes that are unused or already defined. 830 if (!IsUsed(node) || IsDefined(node)) continue; 831 // Generate code for this node "top down", but schedule the code "bottom 832 // up". 833 size_t current_node_end = instructions_.size(); 834 VisitNode(node); 835 if (instruction_selection_failed()) return; 836 std::reverse(instructions_.begin() + current_node_end, instructions_.end()); 837 if (instructions_.size() == current_node_end) continue; 838 // Mark source position on first instruction emitted. 839 SourcePosition source_position = source_positions_->GetSourcePosition(node); 840 if (source_position.IsKnown() && 841 (source_position_mode_ == kAllSourcePositions || 842 node->opcode() == IrOpcode::kCall)) { 843 sequence()->SetSourcePosition(instructions_[current_node_end], 844 source_position); 845 } 846 } 847 848 // We're done with the block. 849 InstructionBlock* instruction_block = 850 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); 851 instruction_block->set_code_start(static_cast<int>(instructions_.size())); 852 instruction_block->set_code_end(current_block_end); 853 854 current_block_ = nullptr; 855 } 856 857 858 void InstructionSelector::VisitControl(BasicBlock* block) { 859 #ifdef DEBUG 860 // SSA deconstruction requires targets of branches not to have phis. 861 // Edge split form guarantees this property, but is more strict. 862 if (block->SuccessorCount() > 1) { 863 for (BasicBlock* const successor : block->successors()) { 864 for (Node* const node : *successor) { 865 CHECK(!IrOpcode::IsPhiOpcode(node->opcode())); 866 } 867 } 868 } 869 #endif 870 871 Node* input = block->control_input(); 872 switch (block->control()) { 873 case BasicBlock::kGoto: 874 return VisitGoto(block->SuccessorAt(0)); 875 case BasicBlock::kCall: { 876 DCHECK_EQ(IrOpcode::kCall, input->opcode()); 877 BasicBlock* success = block->SuccessorAt(0); 878 BasicBlock* exception = block->SuccessorAt(1); 879 return VisitCall(input, exception), VisitGoto(success); 880 } 881 case BasicBlock::kTailCall: { 882 DCHECK_EQ(IrOpcode::kTailCall, input->opcode()); 883 return VisitTailCall(input); 884 } 885 case BasicBlock::kBranch: { 886 DCHECK_EQ(IrOpcode::kBranch, input->opcode()); 887 BasicBlock* tbranch = block->SuccessorAt(0); 888 BasicBlock* fbranch = block->SuccessorAt(1); 889 if (tbranch == fbranch) return VisitGoto(tbranch); 890 return VisitBranch(input, tbranch, fbranch); 891 } 892 case BasicBlock::kSwitch: { 893 DCHECK_EQ(IrOpcode::kSwitch, input->opcode()); 894 SwitchInfo sw; 895 // Last successor must be Default. 896 sw.default_branch = block->successors().back(); 897 DCHECK_EQ(IrOpcode::kIfDefault, sw.default_branch->front()->opcode()); 898 // All other successors must be cases. 899 sw.case_count = block->SuccessorCount() - 1; 900 sw.case_branches = &block->successors().front(); 901 // Determine case values and their min/max. 902 sw.case_values = zone()->NewArray<int32_t>(sw.case_count); 903 sw.min_value = std::numeric_limits<int32_t>::max(); 904 sw.max_value = std::numeric_limits<int32_t>::min(); 905 for (size_t index = 0; index < sw.case_count; ++index) { 906 BasicBlock* branch = sw.case_branches[index]; 907 int32_t value = OpParameter<int32_t>(branch->front()->op()); 908 sw.case_values[index] = value; 909 if (sw.min_value > value) sw.min_value = value; 910 if (sw.max_value < value) sw.max_value = value; 911 } 912 DCHECK_LE(sw.min_value, sw.max_value); 913 // Note that {value_range} can be 0 if {min_value} is -2^31 and 914 // {max_value} 915 // is 2^31-1, so don't assume that it's non-zero below. 916 sw.value_range = 1u + bit_cast<uint32_t>(sw.max_value) - 917 bit_cast<uint32_t>(sw.min_value); 918 return VisitSwitch(input, sw); 919 } 920 case BasicBlock::kReturn: { 921 DCHECK_EQ(IrOpcode::kReturn, input->opcode()); 922 return VisitReturn(input); 923 } 924 case BasicBlock::kDeoptimize: { 925 DeoptimizeParameters p = DeoptimizeParametersOf(input->op()); 926 Node* value = input->InputAt(0); 927 return VisitDeoptimize(p.kind(), p.reason(), value); 928 } 929 case BasicBlock::kThrow: 930 DCHECK_EQ(IrOpcode::kThrow, input->opcode()); 931 return VisitThrow(input->InputAt(0)); 932 case BasicBlock::kNone: { 933 // Exit block doesn't have control. 934 DCHECK_NULL(input); 935 break; 936 } 937 default: 938 UNREACHABLE(); 939 break; 940 } 941 } 942 943 void InstructionSelector::MarkPairProjectionsAsWord32(Node* node) { 944 Node* projection0 = NodeProperties::FindProjection(node, 0); 945 if (projection0) { 946 MarkAsWord32(projection0); 947 } 948 Node* projection1 = NodeProperties::FindProjection(node, 1); 949 if (projection1) { 950 MarkAsWord32(projection1); 951 } 952 } 953 954 void InstructionSelector::VisitNode(Node* node) { 955 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes. 956 switch (node->opcode()) { 957 case IrOpcode::kStart: 958 case IrOpcode::kLoop: 959 case IrOpcode::kEnd: 960 case IrOpcode::kBranch: 961 case IrOpcode::kIfTrue: 962 case IrOpcode::kIfFalse: 963 case IrOpcode::kIfSuccess: 964 case IrOpcode::kSwitch: 965 case IrOpcode::kIfValue: 966 case IrOpcode::kIfDefault: 967 case IrOpcode::kEffectPhi: 968 case IrOpcode::kMerge: 969 case IrOpcode::kTerminate: 970 case IrOpcode::kBeginRegion: 971 // No code needed for these graph artifacts. 972 return; 973 case IrOpcode::kIfException: 974 return MarkAsReference(node), VisitIfException(node); 975 case IrOpcode::kFinishRegion: 976 return MarkAsReference(node), VisitFinishRegion(node); 977 case IrOpcode::kParameter: { 978 MachineType type = 979 linkage()->GetParameterType(ParameterIndexOf(node->op())); 980 MarkAsRepresentation(type.representation(), node); 981 return VisitParameter(node); 982 } 983 case IrOpcode::kOsrValue: 984 return MarkAsReference(node), VisitOsrValue(node); 985 case IrOpcode::kPhi: { 986 MachineRepresentation rep = PhiRepresentationOf(node->op()); 987 if (rep == MachineRepresentation::kNone) return; 988 MarkAsRepresentation(rep, node); 989 return VisitPhi(node); 990 } 991 case IrOpcode::kProjection: 992 return VisitProjection(node); 993 case IrOpcode::kInt32Constant: 994 case IrOpcode::kInt64Constant: 995 case IrOpcode::kExternalConstant: 996 case IrOpcode::kRelocatableInt32Constant: 997 case IrOpcode::kRelocatableInt64Constant: 998 return VisitConstant(node); 999 case IrOpcode::kFloat32Constant: 1000 return MarkAsFloat32(node), VisitConstant(node); 1001 case IrOpcode::kFloat64Constant: 1002 return MarkAsFloat64(node), VisitConstant(node); 1003 case IrOpcode::kHeapConstant: 1004 return MarkAsReference(node), VisitConstant(node); 1005 case IrOpcode::kNumberConstant: { 1006 double value = OpParameter<double>(node); 1007 if (!IsSmiDouble(value)) MarkAsReference(node); 1008 return VisitConstant(node); 1009 } 1010 case IrOpcode::kCall: 1011 return VisitCall(node); 1012 case IrOpcode::kDeoptimizeIf: 1013 return VisitDeoptimizeIf(node); 1014 case IrOpcode::kDeoptimizeUnless: 1015 return VisitDeoptimizeUnless(node); 1016 case IrOpcode::kFrameState: 1017 case IrOpcode::kStateValues: 1018 case IrOpcode::kObjectState: 1019 return; 1020 case IrOpcode::kDebugBreak: 1021 VisitDebugBreak(node); 1022 return; 1023 case IrOpcode::kComment: 1024 VisitComment(node); 1025 return; 1026 case IrOpcode::kRetain: 1027 VisitRetain(node); 1028 return; 1029 case IrOpcode::kLoad: { 1030 LoadRepresentation type = LoadRepresentationOf(node->op()); 1031 MarkAsRepresentation(type.representation(), node); 1032 return VisitLoad(node); 1033 } 1034 case IrOpcode::kStore: 1035 return VisitStore(node); 1036 case IrOpcode::kWord32And: 1037 return MarkAsWord32(node), VisitWord32And(node); 1038 case IrOpcode::kWord32Or: 1039 return MarkAsWord32(node), VisitWord32Or(node); 1040 case IrOpcode::kWord32Xor: 1041 return MarkAsWord32(node), VisitWord32Xor(node); 1042 case IrOpcode::kWord32Shl: 1043 return MarkAsWord32(node), VisitWord32Shl(node); 1044 case IrOpcode::kWord32Shr: 1045 return MarkAsWord32(node), VisitWord32Shr(node); 1046 case IrOpcode::kWord32Sar: 1047 return MarkAsWord32(node), VisitWord32Sar(node); 1048 case IrOpcode::kWord32Ror: 1049 return MarkAsWord32(node), VisitWord32Ror(node); 1050 case IrOpcode::kWord32Equal: 1051 return VisitWord32Equal(node); 1052 case IrOpcode::kWord32Clz: 1053 return MarkAsWord32(node), VisitWord32Clz(node); 1054 case IrOpcode::kWord32Ctz: 1055 return MarkAsWord32(node), VisitWord32Ctz(node); 1056 case IrOpcode::kWord32ReverseBits: 1057 return MarkAsWord32(node), VisitWord32ReverseBits(node); 1058 case IrOpcode::kWord32ReverseBytes: 1059 return MarkAsWord32(node), VisitWord32ReverseBytes(node); 1060 case IrOpcode::kWord32Popcnt: 1061 return MarkAsWord32(node), VisitWord32Popcnt(node); 1062 case IrOpcode::kWord64Popcnt: 1063 return MarkAsWord32(node), VisitWord64Popcnt(node); 1064 case IrOpcode::kWord64And: 1065 return MarkAsWord64(node), VisitWord64And(node); 1066 case IrOpcode::kWord64Or: 1067 return MarkAsWord64(node), VisitWord64Or(node); 1068 case IrOpcode::kWord64Xor: 1069 return MarkAsWord64(node), VisitWord64Xor(node); 1070 case IrOpcode::kWord64Shl: 1071 return MarkAsWord64(node), VisitWord64Shl(node); 1072 case IrOpcode::kWord64Shr: 1073 return MarkAsWord64(node), VisitWord64Shr(node); 1074 case IrOpcode::kWord64Sar: 1075 return MarkAsWord64(node), VisitWord64Sar(node); 1076 case IrOpcode::kWord64Ror: 1077 return MarkAsWord64(node), VisitWord64Ror(node); 1078 case IrOpcode::kWord64Clz: 1079 return MarkAsWord64(node), VisitWord64Clz(node); 1080 case IrOpcode::kWord64Ctz: 1081 return MarkAsWord64(node), VisitWord64Ctz(node); 1082 case IrOpcode::kWord64ReverseBits: 1083 return MarkAsWord64(node), VisitWord64ReverseBits(node); 1084 case IrOpcode::kWord64ReverseBytes: 1085 return MarkAsWord64(node), VisitWord64ReverseBytes(node); 1086 case IrOpcode::kWord64Equal: 1087 return VisitWord64Equal(node); 1088 case IrOpcode::kInt32Add: 1089 return MarkAsWord32(node), VisitInt32Add(node); 1090 case IrOpcode::kInt32AddWithOverflow: 1091 return MarkAsWord32(node), VisitInt32AddWithOverflow(node); 1092 case IrOpcode::kInt32Sub: 1093 return MarkAsWord32(node), VisitInt32Sub(node); 1094 case IrOpcode::kInt32SubWithOverflow: 1095 return VisitInt32SubWithOverflow(node); 1096 case IrOpcode::kInt32Mul: 1097 return MarkAsWord32(node), VisitInt32Mul(node); 1098 case IrOpcode::kInt32MulWithOverflow: 1099 return MarkAsWord32(node), VisitInt32MulWithOverflow(node); 1100 case IrOpcode::kInt32MulHigh: 1101 return VisitInt32MulHigh(node); 1102 case IrOpcode::kInt32Div: 1103 return MarkAsWord32(node), VisitInt32Div(node); 1104 case IrOpcode::kInt32Mod: 1105 return MarkAsWord32(node), VisitInt32Mod(node); 1106 case IrOpcode::kInt32LessThan: 1107 return VisitInt32LessThan(node); 1108 case IrOpcode::kInt32LessThanOrEqual: 1109 return VisitInt32LessThanOrEqual(node); 1110 case IrOpcode::kUint32Div: 1111 return MarkAsWord32(node), VisitUint32Div(node); 1112 case IrOpcode::kUint32LessThan: 1113 return VisitUint32LessThan(node); 1114 case IrOpcode::kUint32LessThanOrEqual: 1115 return VisitUint32LessThanOrEqual(node); 1116 case IrOpcode::kUint32Mod: 1117 return MarkAsWord32(node), VisitUint32Mod(node); 1118 case IrOpcode::kUint32MulHigh: 1119 return VisitUint32MulHigh(node); 1120 case IrOpcode::kInt64Add: 1121 return MarkAsWord64(node), VisitInt64Add(node); 1122 case IrOpcode::kInt64AddWithOverflow: 1123 return MarkAsWord64(node), VisitInt64AddWithOverflow(node); 1124 case IrOpcode::kInt64Sub: 1125 return MarkAsWord64(node), VisitInt64Sub(node); 1126 case IrOpcode::kInt64SubWithOverflow: 1127 return MarkAsWord64(node), VisitInt64SubWithOverflow(node); 1128 case IrOpcode::kInt64Mul: 1129 return MarkAsWord64(node), VisitInt64Mul(node); 1130 case IrOpcode::kInt64Div: 1131 return MarkAsWord64(node), VisitInt64Div(node); 1132 case IrOpcode::kInt64Mod: 1133 return MarkAsWord64(node), VisitInt64Mod(node); 1134 case IrOpcode::kInt64LessThan: 1135 return VisitInt64LessThan(node); 1136 case IrOpcode::kInt64LessThanOrEqual: 1137 return VisitInt64LessThanOrEqual(node); 1138 case IrOpcode::kUint64Div: 1139 return MarkAsWord64(node), VisitUint64Div(node); 1140 case IrOpcode::kUint64LessThan: 1141 return VisitUint64LessThan(node); 1142 case IrOpcode::kUint64LessThanOrEqual: 1143 return VisitUint64LessThanOrEqual(node); 1144 case IrOpcode::kUint64Mod: 1145 return MarkAsWord64(node), VisitUint64Mod(node); 1146 case IrOpcode::kBitcastTaggedToWord: 1147 return MarkAsRepresentation(MachineType::PointerRepresentation(), node), 1148 VisitBitcastTaggedToWord(node); 1149 case IrOpcode::kBitcastWordToTagged: 1150 return MarkAsReference(node), VisitBitcastWordToTagged(node); 1151 case IrOpcode::kBitcastWordToTaggedSigned: 1152 return MarkAsRepresentation(MachineRepresentation::kTaggedSigned, node), 1153 EmitIdentity(node); 1154 case IrOpcode::kChangeFloat32ToFloat64: 1155 return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node); 1156 case IrOpcode::kChangeInt32ToFloat64: 1157 return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node); 1158 case IrOpcode::kChangeUint32ToFloat64: 1159 return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node); 1160 case IrOpcode::kChangeFloat64ToInt32: 1161 return MarkAsWord32(node), VisitChangeFloat64ToInt32(node); 1162 case IrOpcode::kChangeFloat64ToUint32: 1163 return MarkAsWord32(node), VisitChangeFloat64ToUint32(node); 1164 case IrOpcode::kFloat64SilenceNaN: 1165 MarkAsFloat64(node); 1166 if (CanProduceSignalingNaN(node->InputAt(0))) { 1167 return VisitFloat64SilenceNaN(node); 1168 } else { 1169 return EmitIdentity(node); 1170 } 1171 case IrOpcode::kTruncateFloat64ToUint32: 1172 return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node); 1173 case IrOpcode::kTruncateFloat32ToInt32: 1174 return MarkAsWord32(node), VisitTruncateFloat32ToInt32(node); 1175 case IrOpcode::kTruncateFloat32ToUint32: 1176 return MarkAsWord32(node), VisitTruncateFloat32ToUint32(node); 1177 case IrOpcode::kTryTruncateFloat32ToInt64: 1178 return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node); 1179 case IrOpcode::kTryTruncateFloat64ToInt64: 1180 return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node); 1181 case IrOpcode::kTryTruncateFloat32ToUint64: 1182 return MarkAsWord64(node), VisitTryTruncateFloat32ToUint64(node); 1183 case IrOpcode::kTryTruncateFloat64ToUint64: 1184 return MarkAsWord64(node), VisitTryTruncateFloat64ToUint64(node); 1185 case IrOpcode::kChangeInt32ToInt64: 1186 return MarkAsWord64(node), VisitChangeInt32ToInt64(node); 1187 case IrOpcode::kChangeUint32ToUint64: 1188 return MarkAsWord64(node), VisitChangeUint32ToUint64(node); 1189 case IrOpcode::kTruncateFloat64ToFloat32: 1190 return MarkAsFloat32(node), VisitTruncateFloat64ToFloat32(node); 1191 case IrOpcode::kTruncateFloat64ToWord32: 1192 return MarkAsWord32(node), VisitTruncateFloat64ToWord32(node); 1193 case IrOpcode::kTruncateInt64ToInt32: 1194 return MarkAsWord32(node), VisitTruncateInt64ToInt32(node); 1195 case IrOpcode::kRoundFloat64ToInt32: 1196 return MarkAsWord32(node), VisitRoundFloat64ToInt32(node); 1197 case IrOpcode::kRoundInt64ToFloat32: 1198 return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node); 1199 case IrOpcode::kRoundInt32ToFloat32: 1200 return MarkAsFloat32(node), VisitRoundInt32ToFloat32(node); 1201 case IrOpcode::kRoundInt64ToFloat64: 1202 return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node); 1203 case IrOpcode::kBitcastFloat32ToInt32: 1204 return MarkAsWord32(node), VisitBitcastFloat32ToInt32(node); 1205 case IrOpcode::kRoundUint32ToFloat32: 1206 return MarkAsFloat32(node), VisitRoundUint32ToFloat32(node); 1207 case IrOpcode::kRoundUint64ToFloat32: 1208 return MarkAsFloat64(node), VisitRoundUint64ToFloat32(node); 1209 case IrOpcode::kRoundUint64ToFloat64: 1210 return MarkAsFloat64(node), VisitRoundUint64ToFloat64(node); 1211 case IrOpcode::kBitcastFloat64ToInt64: 1212 return MarkAsWord64(node), VisitBitcastFloat64ToInt64(node); 1213 case IrOpcode::kBitcastInt32ToFloat32: 1214 return MarkAsFloat32(node), VisitBitcastInt32ToFloat32(node); 1215 case IrOpcode::kBitcastInt64ToFloat64: 1216 return MarkAsFloat64(node), VisitBitcastInt64ToFloat64(node); 1217 case IrOpcode::kFloat32Add: 1218 return MarkAsFloat32(node), VisitFloat32Add(node); 1219 case IrOpcode::kFloat32Sub: 1220 return MarkAsFloat32(node), VisitFloat32Sub(node); 1221 case IrOpcode::kFloat32Neg: 1222 return MarkAsFloat32(node), VisitFloat32Neg(node); 1223 case IrOpcode::kFloat32Mul: 1224 return MarkAsFloat32(node), VisitFloat32Mul(node); 1225 case IrOpcode::kFloat32Div: 1226 return MarkAsFloat32(node), VisitFloat32Div(node); 1227 case IrOpcode::kFloat32Abs: 1228 return MarkAsFloat32(node), VisitFloat32Abs(node); 1229 case IrOpcode::kFloat32Sqrt: 1230 return MarkAsFloat32(node), VisitFloat32Sqrt(node); 1231 case IrOpcode::kFloat32Equal: 1232 return VisitFloat32Equal(node); 1233 case IrOpcode::kFloat32LessThan: 1234 return VisitFloat32LessThan(node); 1235 case IrOpcode::kFloat32LessThanOrEqual: 1236 return VisitFloat32LessThanOrEqual(node); 1237 case IrOpcode::kFloat32Max: 1238 return MarkAsFloat32(node), VisitFloat32Max(node); 1239 case IrOpcode::kFloat32Min: 1240 return MarkAsFloat32(node), VisitFloat32Min(node); 1241 case IrOpcode::kFloat64Add: 1242 return MarkAsFloat64(node), VisitFloat64Add(node); 1243 case IrOpcode::kFloat64Sub: 1244 return MarkAsFloat64(node), VisitFloat64Sub(node); 1245 case IrOpcode::kFloat64Neg: 1246 return MarkAsFloat64(node), VisitFloat64Neg(node); 1247 case IrOpcode::kFloat64Mul: 1248 return MarkAsFloat64(node), VisitFloat64Mul(node); 1249 case IrOpcode::kFloat64Div: 1250 return MarkAsFloat64(node), VisitFloat64Div(node); 1251 case IrOpcode::kFloat64Mod: 1252 return MarkAsFloat64(node), VisitFloat64Mod(node); 1253 case IrOpcode::kFloat64Min: 1254 return MarkAsFloat64(node), VisitFloat64Min(node); 1255 case IrOpcode::kFloat64Max: 1256 return MarkAsFloat64(node), VisitFloat64Max(node); 1257 case IrOpcode::kFloat64Abs: 1258 return MarkAsFloat64(node), VisitFloat64Abs(node); 1259 case IrOpcode::kFloat64Acos: 1260 return MarkAsFloat64(node), VisitFloat64Acos(node); 1261 case IrOpcode::kFloat64Acosh: 1262 return MarkAsFloat64(node), VisitFloat64Acosh(node); 1263 case IrOpcode::kFloat64Asin: 1264 return MarkAsFloat64(node), VisitFloat64Asin(node); 1265 case IrOpcode::kFloat64Asinh: 1266 return MarkAsFloat64(node), VisitFloat64Asinh(node); 1267 case IrOpcode::kFloat64Atan: 1268 return MarkAsFloat64(node), VisitFloat64Atan(node); 1269 case IrOpcode::kFloat64Atanh: 1270 return MarkAsFloat64(node), VisitFloat64Atanh(node); 1271 case IrOpcode::kFloat64Atan2: 1272 return MarkAsFloat64(node), VisitFloat64Atan2(node); 1273 case IrOpcode::kFloat64Cbrt: 1274 return MarkAsFloat64(node), VisitFloat64Cbrt(node); 1275 case IrOpcode::kFloat64Cos: 1276 return MarkAsFloat64(node), VisitFloat64Cos(node); 1277 case IrOpcode::kFloat64Cosh: 1278 return MarkAsFloat64(node), VisitFloat64Cosh(node); 1279 case IrOpcode::kFloat64Exp: 1280 return MarkAsFloat64(node), VisitFloat64Exp(node); 1281 case IrOpcode::kFloat64Expm1: 1282 return MarkAsFloat64(node), VisitFloat64Expm1(node); 1283 case IrOpcode::kFloat64Log: 1284 return MarkAsFloat64(node), VisitFloat64Log(node); 1285 case IrOpcode::kFloat64Log1p: 1286 return MarkAsFloat64(node), VisitFloat64Log1p(node); 1287 case IrOpcode::kFloat64Log10: 1288 return MarkAsFloat64(node), VisitFloat64Log10(node); 1289 case IrOpcode::kFloat64Log2: 1290 return MarkAsFloat64(node), VisitFloat64Log2(node); 1291 case IrOpcode::kFloat64Pow: 1292 return MarkAsFloat64(node), VisitFloat64Pow(node); 1293 case IrOpcode::kFloat64Sin: 1294 return MarkAsFloat64(node), VisitFloat64Sin(node); 1295 case IrOpcode::kFloat64Sinh: 1296 return MarkAsFloat64(node), VisitFloat64Sinh(node); 1297 case IrOpcode::kFloat64Sqrt: 1298 return MarkAsFloat64(node), VisitFloat64Sqrt(node); 1299 case IrOpcode::kFloat64Tan: 1300 return MarkAsFloat64(node), VisitFloat64Tan(node); 1301 case IrOpcode::kFloat64Tanh: 1302 return MarkAsFloat64(node), VisitFloat64Tanh(node); 1303 case IrOpcode::kFloat64Equal: 1304 return VisitFloat64Equal(node); 1305 case IrOpcode::kFloat64LessThan: 1306 return VisitFloat64LessThan(node); 1307 case IrOpcode::kFloat64LessThanOrEqual: 1308 return VisitFloat64LessThanOrEqual(node); 1309 case IrOpcode::kFloat32RoundDown: 1310 return MarkAsFloat32(node), VisitFloat32RoundDown(node); 1311 case IrOpcode::kFloat64RoundDown: 1312 return MarkAsFloat64(node), VisitFloat64RoundDown(node); 1313 case IrOpcode::kFloat32RoundUp: 1314 return MarkAsFloat32(node), VisitFloat32RoundUp(node); 1315 case IrOpcode::kFloat64RoundUp: 1316 return MarkAsFloat64(node), VisitFloat64RoundUp(node); 1317 case IrOpcode::kFloat32RoundTruncate: 1318 return MarkAsFloat32(node), VisitFloat32RoundTruncate(node); 1319 case IrOpcode::kFloat64RoundTruncate: 1320 return MarkAsFloat64(node), VisitFloat64RoundTruncate(node); 1321 case IrOpcode::kFloat64RoundTiesAway: 1322 return MarkAsFloat64(node), VisitFloat64RoundTiesAway(node); 1323 case IrOpcode::kFloat32RoundTiesEven: 1324 return MarkAsFloat32(node), VisitFloat32RoundTiesEven(node); 1325 case IrOpcode::kFloat64RoundTiesEven: 1326 return MarkAsFloat64(node), VisitFloat64RoundTiesEven(node); 1327 case IrOpcode::kFloat64ExtractLowWord32: 1328 return MarkAsWord32(node), VisitFloat64ExtractLowWord32(node); 1329 case IrOpcode::kFloat64ExtractHighWord32: 1330 return MarkAsWord32(node), VisitFloat64ExtractHighWord32(node); 1331 case IrOpcode::kFloat64InsertLowWord32: 1332 return MarkAsFloat64(node), VisitFloat64InsertLowWord32(node); 1333 case IrOpcode::kFloat64InsertHighWord32: 1334 return MarkAsFloat64(node), VisitFloat64InsertHighWord32(node); 1335 case IrOpcode::kStackSlot: 1336 return VisitStackSlot(node); 1337 case IrOpcode::kLoadStackPointer: 1338 return VisitLoadStackPointer(node); 1339 case IrOpcode::kLoadFramePointer: 1340 return VisitLoadFramePointer(node); 1341 case IrOpcode::kLoadParentFramePointer: 1342 return VisitLoadParentFramePointer(node); 1343 case IrOpcode::kUnalignedLoad: { 1344 UnalignedLoadRepresentation type = 1345 UnalignedLoadRepresentationOf(node->op()); 1346 MarkAsRepresentation(type.representation(), node); 1347 return VisitUnalignedLoad(node); 1348 } 1349 case IrOpcode::kUnalignedStore: 1350 return VisitUnalignedStore(node); 1351 case IrOpcode::kCheckedLoad: { 1352 MachineRepresentation rep = 1353 CheckedLoadRepresentationOf(node->op()).representation(); 1354 MarkAsRepresentation(rep, node); 1355 return VisitCheckedLoad(node); 1356 } 1357 case IrOpcode::kCheckedStore: 1358 return VisitCheckedStore(node); 1359 case IrOpcode::kInt32PairAdd: 1360 MarkAsWord32(node); 1361 MarkPairProjectionsAsWord32(node); 1362 return VisitInt32PairAdd(node); 1363 case IrOpcode::kInt32PairSub: 1364 MarkAsWord32(node); 1365 MarkPairProjectionsAsWord32(node); 1366 return VisitInt32PairSub(node); 1367 case IrOpcode::kInt32PairMul: 1368 MarkAsWord32(node); 1369 MarkPairProjectionsAsWord32(node); 1370 return VisitInt32PairMul(node); 1371 case IrOpcode::kWord32PairShl: 1372 MarkAsWord32(node); 1373 MarkPairProjectionsAsWord32(node); 1374 return VisitWord32PairShl(node); 1375 case IrOpcode::kWord32PairShr: 1376 MarkAsWord32(node); 1377 MarkPairProjectionsAsWord32(node); 1378 return VisitWord32PairShr(node); 1379 case IrOpcode::kWord32PairSar: 1380 MarkAsWord32(node); 1381 MarkPairProjectionsAsWord32(node); 1382 return VisitWord32PairSar(node); 1383 case IrOpcode::kAtomicLoad: { 1384 LoadRepresentation type = LoadRepresentationOf(node->op()); 1385 MarkAsRepresentation(type.representation(), node); 1386 return VisitAtomicLoad(node); 1387 } 1388 case IrOpcode::kAtomicStore: 1389 return VisitAtomicStore(node); 1390 case IrOpcode::kProtectedLoad: 1391 return VisitProtectedLoad(node); 1392 case IrOpcode::kUnsafePointerAdd: 1393 MarkAsRepresentation(MachineType::PointerRepresentation(), node); 1394 return VisitUnsafePointerAdd(node); 1395 case IrOpcode::kCreateInt32x4: 1396 return MarkAsSimd128(node), VisitCreateInt32x4(node); 1397 case IrOpcode::kInt32x4ExtractLane: 1398 return MarkAsWord32(node), VisitInt32x4ExtractLane(node); 1399 default: 1400 V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d", 1401 node->opcode(), node->op()->mnemonic(), node->id()); 1402 break; 1403 } 1404 } 1405 1406 void InstructionSelector::VisitLoadStackPointer(Node* node) { 1407 OperandGenerator g(this); 1408 Emit(kArchStackPointer, g.DefineAsRegister(node)); 1409 } 1410 1411 void InstructionSelector::VisitLoadFramePointer(Node* node) { 1412 OperandGenerator g(this); 1413 Emit(kArchFramePointer, g.DefineAsRegister(node)); 1414 } 1415 1416 void InstructionSelector::VisitLoadParentFramePointer(Node* node) { 1417 OperandGenerator g(this); 1418 Emit(kArchParentFramePointer, g.DefineAsRegister(node)); 1419 } 1420 1421 void InstructionSelector::VisitFloat64Acos(Node* node) { 1422 VisitFloat64Ieee754Unop(node, kIeee754Float64Acos); 1423 } 1424 1425 void InstructionSelector::VisitFloat64Acosh(Node* node) { 1426 VisitFloat64Ieee754Unop(node, kIeee754Float64Acosh); 1427 } 1428 1429 void InstructionSelector::VisitFloat64Asin(Node* node) { 1430 VisitFloat64Ieee754Unop(node, kIeee754Float64Asin); 1431 } 1432 1433 void InstructionSelector::VisitFloat64Asinh(Node* node) { 1434 VisitFloat64Ieee754Unop(node, kIeee754Float64Asinh); 1435 } 1436 1437 void InstructionSelector::VisitFloat64Atan(Node* node) { 1438 VisitFloat64Ieee754Unop(node, kIeee754Float64Atan); 1439 } 1440 1441 void InstructionSelector::VisitFloat64Atanh(Node* node) { 1442 VisitFloat64Ieee754Unop(node, kIeee754Float64Atanh); 1443 } 1444 1445 void InstructionSelector::VisitFloat64Atan2(Node* node) { 1446 VisitFloat64Ieee754Binop(node, kIeee754Float64Atan2); 1447 } 1448 1449 void InstructionSelector::VisitFloat64Cbrt(Node* node) { 1450 VisitFloat64Ieee754Unop(node, kIeee754Float64Cbrt); 1451 } 1452 1453 void InstructionSelector::VisitFloat64Cos(Node* node) { 1454 VisitFloat64Ieee754Unop(node, kIeee754Float64Cos); 1455 } 1456 1457 void InstructionSelector::VisitFloat64Cosh(Node* node) { 1458 VisitFloat64Ieee754Unop(node, kIeee754Float64Cosh); 1459 } 1460 1461 void InstructionSelector::VisitFloat64Exp(Node* node) { 1462 VisitFloat64Ieee754Unop(node, kIeee754Float64Exp); 1463 } 1464 1465 void InstructionSelector::VisitFloat64Expm1(Node* node) { 1466 VisitFloat64Ieee754Unop(node, kIeee754Float64Expm1); 1467 } 1468 1469 void InstructionSelector::VisitFloat64Log(Node* node) { 1470 VisitFloat64Ieee754Unop(node, kIeee754Float64Log); 1471 } 1472 1473 void InstructionSelector::VisitFloat64Log1p(Node* node) { 1474 VisitFloat64Ieee754Unop(node, kIeee754Float64Log1p); 1475 } 1476 1477 void InstructionSelector::VisitFloat64Log2(Node* node) { 1478 VisitFloat64Ieee754Unop(node, kIeee754Float64Log2); 1479 } 1480 1481 void InstructionSelector::VisitFloat64Log10(Node* node) { 1482 VisitFloat64Ieee754Unop(node, kIeee754Float64Log10); 1483 } 1484 1485 void InstructionSelector::VisitFloat64Pow(Node* node) { 1486 VisitFloat64Ieee754Binop(node, kIeee754Float64Pow); 1487 } 1488 1489 void InstructionSelector::VisitFloat64Sin(Node* node) { 1490 VisitFloat64Ieee754Unop(node, kIeee754Float64Sin); 1491 } 1492 1493 void InstructionSelector::VisitFloat64Sinh(Node* node) { 1494 VisitFloat64Ieee754Unop(node, kIeee754Float64Sinh); 1495 } 1496 1497 void InstructionSelector::VisitFloat64Tan(Node* node) { 1498 VisitFloat64Ieee754Unop(node, kIeee754Float64Tan); 1499 } 1500 1501 void InstructionSelector::VisitFloat64Tanh(Node* node) { 1502 VisitFloat64Ieee754Unop(node, kIeee754Float64Tanh); 1503 } 1504 1505 void InstructionSelector::EmitTableSwitch(const SwitchInfo& sw, 1506 InstructionOperand& index_operand) { 1507 OperandGenerator g(this); 1508 size_t input_count = 2 + sw.value_range; 1509 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); 1510 inputs[0] = index_operand; 1511 InstructionOperand default_operand = g.Label(sw.default_branch); 1512 std::fill(&inputs[1], &inputs[input_count], default_operand); 1513 for (size_t index = 0; index < sw.case_count; ++index) { 1514 size_t value = sw.case_values[index] - sw.min_value; 1515 BasicBlock* branch = sw.case_branches[index]; 1516 DCHECK_LE(0u, value); 1517 DCHECK_LT(value + 2, input_count); 1518 inputs[value + 2] = g.Label(branch); 1519 } 1520 Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr); 1521 } 1522 1523 1524 void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw, 1525 InstructionOperand& value_operand) { 1526 OperandGenerator g(this); 1527 size_t input_count = 2 + sw.case_count * 2; 1528 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); 1529 inputs[0] = value_operand; 1530 inputs[1] = g.Label(sw.default_branch); 1531 for (size_t index = 0; index < sw.case_count; ++index) { 1532 int32_t value = sw.case_values[index]; 1533 BasicBlock* branch = sw.case_branches[index]; 1534 inputs[index * 2 + 2 + 0] = g.TempImmediate(value); 1535 inputs[index * 2 + 2 + 1] = g.Label(branch); 1536 } 1537 Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr); 1538 } 1539 1540 void InstructionSelector::VisitStackSlot(Node* node) { 1541 int size = 1 << ElementSizeLog2Of(StackSlotRepresentationOf(node->op())); 1542 int slot = frame_->AllocateSpillSlot(size); 1543 OperandGenerator g(this); 1544 1545 Emit(kArchStackSlot, g.DefineAsRegister(node), 1546 sequence()->AddImmediate(Constant(slot)), 0, nullptr); 1547 } 1548 1549 void InstructionSelector::VisitBitcastTaggedToWord(Node* node) { 1550 OperandGenerator g(this); 1551 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(node->InputAt(0))); 1552 } 1553 1554 void InstructionSelector::VisitBitcastWordToTagged(Node* node) { 1555 OperandGenerator g(this); 1556 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(node->InputAt(0))); 1557 } 1558 1559 // 32 bit targets do not implement the following instructions. 1560 #if V8_TARGET_ARCH_32_BIT 1561 1562 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); } 1563 1564 1565 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); } 1566 1567 1568 void InstructionSelector::VisitWord64Xor(Node* node) { UNIMPLEMENTED(); } 1569 1570 1571 void InstructionSelector::VisitWord64Shl(Node* node) { UNIMPLEMENTED(); } 1572 1573 1574 void InstructionSelector::VisitWord64Shr(Node* node) { UNIMPLEMENTED(); } 1575 1576 1577 void InstructionSelector::VisitWord64Sar(Node* node) { UNIMPLEMENTED(); } 1578 1579 1580 void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); } 1581 1582 1583 void InstructionSelector::VisitWord64Clz(Node* node) { UNIMPLEMENTED(); } 1584 1585 1586 void InstructionSelector::VisitWord64Ctz(Node* node) { UNIMPLEMENTED(); } 1587 1588 1589 void InstructionSelector::VisitWord64ReverseBits(Node* node) { 1590 UNIMPLEMENTED(); 1591 } 1592 1593 1594 void InstructionSelector::VisitWord64Popcnt(Node* node) { UNIMPLEMENTED(); } 1595 1596 1597 void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); } 1598 1599 1600 void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); } 1601 1602 1603 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { 1604 UNIMPLEMENTED(); 1605 } 1606 1607 1608 void InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); } 1609 1610 1611 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { 1612 UNIMPLEMENTED(); 1613 } 1614 1615 void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); } 1616 1617 1618 void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); } 1619 1620 1621 void InstructionSelector::VisitInt64LessThan(Node* node) { UNIMPLEMENTED(); } 1622 1623 1624 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { 1625 UNIMPLEMENTED(); 1626 } 1627 1628 1629 void InstructionSelector::VisitUint64Div(Node* node) { UNIMPLEMENTED(); } 1630 1631 1632 void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); } 1633 1634 1635 void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); } 1636 1637 1638 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { 1639 UNIMPLEMENTED(); 1640 } 1641 1642 1643 void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); } 1644 1645 1646 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) { 1647 UNIMPLEMENTED(); 1648 } 1649 1650 1651 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { 1652 UNIMPLEMENTED(); 1653 } 1654 1655 1656 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) { 1657 UNIMPLEMENTED(); 1658 } 1659 1660 1661 void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) { 1662 UNIMPLEMENTED(); 1663 } 1664 1665 1666 void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) { 1667 UNIMPLEMENTED(); 1668 } 1669 1670 1671 void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) { 1672 UNIMPLEMENTED(); 1673 } 1674 1675 1676 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { 1677 UNIMPLEMENTED(); 1678 } 1679 1680 1681 void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) { 1682 UNIMPLEMENTED(); 1683 } 1684 1685 1686 void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) { 1687 UNIMPLEMENTED(); 1688 } 1689 1690 1691 void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) { 1692 UNIMPLEMENTED(); 1693 } 1694 1695 1696 void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) { 1697 UNIMPLEMENTED(); 1698 } 1699 1700 1701 void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) { 1702 UNIMPLEMENTED(); 1703 } 1704 1705 1706 void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) { 1707 UNIMPLEMENTED(); 1708 } 1709 #endif // V8_TARGET_ARCH_32_BIT 1710 1711 // 64 bit targets do not implement the following instructions. 1712 #if V8_TARGET_ARCH_64_BIT 1713 void InstructionSelector::VisitInt32PairAdd(Node* node) { UNIMPLEMENTED(); } 1714 1715 void InstructionSelector::VisitInt32PairSub(Node* node) { UNIMPLEMENTED(); } 1716 1717 void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); } 1718 1719 void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); } 1720 1721 void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); } 1722 1723 void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); } 1724 #endif // V8_TARGET_ARCH_64_BIT 1725 1726 #if !V8_TARGET_ARCH_X64 1727 void InstructionSelector::VisitCreateInt32x4(Node* node) { UNIMPLEMENTED(); } 1728 1729 void InstructionSelector::VisitInt32x4ExtractLane(Node* node) { 1730 UNIMPLEMENTED(); 1731 } 1732 #endif // !V8_TARGET_ARCH_X64 1733 1734 void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); } 1735 1736 void InstructionSelector::VisitParameter(Node* node) { 1737 OperandGenerator g(this); 1738 int index = ParameterIndexOf(node->op()); 1739 InstructionOperand op = 1740 linkage()->ParameterHasSecondaryLocation(index) 1741 ? g.DefineAsDualLocation( 1742 node, linkage()->GetParameterLocation(index), 1743 linkage()->GetParameterSecondaryLocation(index)) 1744 : g.DefineAsLocation(node, linkage()->GetParameterLocation(index)); 1745 1746 Emit(kArchNop, op); 1747 } 1748 1749 namespace { 1750 LinkageLocation ExceptionLocation() { 1751 return LinkageLocation::ForRegister(kReturnRegister0.code(), 1752 MachineType::IntPtr()); 1753 } 1754 } 1755 1756 void InstructionSelector::VisitIfException(Node* node) { 1757 OperandGenerator g(this); 1758 DCHECK_EQ(IrOpcode::kCall, node->InputAt(1)->opcode()); 1759 Emit(kArchNop, g.DefineAsLocation(node, ExceptionLocation())); 1760 } 1761 1762 1763 void InstructionSelector::VisitOsrValue(Node* node) { 1764 OperandGenerator g(this); 1765 int index = OsrValueIndexOf(node->op()); 1766 Emit(kArchNop, 1767 g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index))); 1768 } 1769 1770 1771 void InstructionSelector::VisitPhi(Node* node) { 1772 const int input_count = node->op()->ValueInputCount(); 1773 PhiInstruction* phi = new (instruction_zone()) 1774 PhiInstruction(instruction_zone(), GetVirtualRegister(node), 1775 static_cast<size_t>(input_count)); 1776 sequence() 1777 ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number())) 1778 ->AddPhi(phi); 1779 for (int i = 0; i < input_count; ++i) { 1780 Node* const input = node->InputAt(i); 1781 MarkAsUsed(input); 1782 phi->SetInput(static_cast<size_t>(i), GetVirtualRegister(input)); 1783 } 1784 } 1785 1786 1787 void InstructionSelector::VisitProjection(Node* node) { 1788 OperandGenerator g(this); 1789 Node* value = node->InputAt(0); 1790 switch (value->opcode()) { 1791 case IrOpcode::kInt32AddWithOverflow: 1792 case IrOpcode::kInt32SubWithOverflow: 1793 case IrOpcode::kInt32MulWithOverflow: 1794 case IrOpcode::kInt64AddWithOverflow: 1795 case IrOpcode::kInt64SubWithOverflow: 1796 case IrOpcode::kTryTruncateFloat32ToInt64: 1797 case IrOpcode::kTryTruncateFloat64ToInt64: 1798 case IrOpcode::kTryTruncateFloat32ToUint64: 1799 case IrOpcode::kTryTruncateFloat64ToUint64: 1800 case IrOpcode::kInt32PairAdd: 1801 case IrOpcode::kInt32PairSub: 1802 case IrOpcode::kInt32PairMul: 1803 case IrOpcode::kWord32PairShl: 1804 case IrOpcode::kWord32PairShr: 1805 case IrOpcode::kWord32PairSar: 1806 if (ProjectionIndexOf(node->op()) == 0u) { 1807 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); 1808 } else { 1809 DCHECK(ProjectionIndexOf(node->op()) == 1u); 1810 MarkAsUsed(value); 1811 } 1812 break; 1813 default: 1814 break; 1815 } 1816 } 1817 1818 1819 void InstructionSelector::VisitConstant(Node* node) { 1820 // We must emit a NOP here because every live range needs a defining 1821 // instruction in the register allocator. 1822 OperandGenerator g(this); 1823 Emit(kArchNop, g.DefineAsConstant(node)); 1824 } 1825 1826 1827 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { 1828 OperandGenerator g(this); 1829 const CallDescriptor* descriptor = CallDescriptorOf(node->op()); 1830 1831 FrameStateDescriptor* frame_state_descriptor = nullptr; 1832 if (descriptor->NeedsFrameState()) { 1833 frame_state_descriptor = GetFrameStateDescriptor( 1834 node->InputAt(static_cast<int>(descriptor->InputCount()))); 1835 } 1836 1837 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); 1838 1839 // Compute InstructionOperands for inputs and outputs. 1840 // TODO(turbofan): on some architectures it's probably better to use 1841 // the code object in a register if there are multiple uses of it. 1842 // Improve constant pool and the heuristics in the register allocator 1843 // for where to emit constants. 1844 CallBufferFlags call_buffer_flags(kCallCodeImmediate | kCallAddressImmediate); 1845 InitializeCallBuffer(node, &buffer, call_buffer_flags); 1846 1847 EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node); 1848 1849 // Pass label of exception handler block. 1850 CallDescriptor::Flags flags = descriptor->flags(); 1851 if (handler) { 1852 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); 1853 flags |= CallDescriptor::kHasExceptionHandler; 1854 buffer.instruction_args.push_back(g.Label(handler)); 1855 } 1856 1857 bool from_native_stack = linkage()->GetIncomingDescriptor()->UseNativeStack(); 1858 bool to_native_stack = descriptor->UseNativeStack(); 1859 if (from_native_stack != to_native_stack) { 1860 // (arm64 only) Mismatch in the use of stack pointers. One or the other 1861 // has to be restored manually by the code generator. 1862 flags |= to_native_stack ? CallDescriptor::kRestoreJSSP 1863 : CallDescriptor::kRestoreCSP; 1864 } 1865 1866 // Select the appropriate opcode based on the call type. 1867 InstructionCode opcode = kArchNop; 1868 switch (descriptor->kind()) { 1869 case CallDescriptor::kCallAddress: 1870 opcode = 1871 kArchCallCFunction | 1872 MiscField::encode(static_cast<int>(descriptor->ParameterCount())); 1873 break; 1874 case CallDescriptor::kCallCodeObject: 1875 opcode = kArchCallCodeObject | MiscField::encode(flags); 1876 break; 1877 case CallDescriptor::kCallJSFunction: 1878 opcode = kArchCallJSFunction | MiscField::encode(flags); 1879 break; 1880 } 1881 1882 // Emit the call instruction. 1883 size_t const output_count = buffer.outputs.size(); 1884 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; 1885 Instruction* call_instr = 1886 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), 1887 &buffer.instruction_args.front()); 1888 if (instruction_selection_failed()) return; 1889 call_instr->MarkAsCall(); 1890 } 1891 1892 1893 void InstructionSelector::VisitTailCall(Node* node) { 1894 OperandGenerator g(this); 1895 CallDescriptor const* descriptor = CallDescriptorOf(node->op()); 1896 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); 1897 1898 CallDescriptor* caller = linkage()->GetIncomingDescriptor(); 1899 DCHECK(caller->CanTailCall(node)); 1900 const CallDescriptor* callee = CallDescriptorOf(node->op()); 1901 int stack_param_delta = callee->GetStackParameterDelta(caller); 1902 CallBuffer buffer(zone(), descriptor, nullptr); 1903 1904 // Compute InstructionOperands for inputs and outputs. 1905 CallBufferFlags flags(kCallCodeImmediate | kCallTail); 1906 if (IsTailCallAddressImmediate()) { 1907 flags |= kCallAddressImmediate; 1908 } 1909 InitializeCallBuffer(node, &buffer, flags, stack_param_delta); 1910 1911 // Select the appropriate opcode based on the call type. 1912 InstructionCode opcode; 1913 InstructionOperandVector temps(zone()); 1914 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { 1915 switch (descriptor->kind()) { 1916 case CallDescriptor::kCallCodeObject: 1917 opcode = kArchTailCallCodeObjectFromJSFunction; 1918 break; 1919 case CallDescriptor::kCallJSFunction: 1920 opcode = kArchTailCallJSFunctionFromJSFunction; 1921 break; 1922 default: 1923 UNREACHABLE(); 1924 return; 1925 } 1926 int temps_count = GetTempsCountForTailCallFromJSFunction(); 1927 for (int i = 0; i < temps_count; i++) { 1928 temps.push_back(g.TempRegister()); 1929 } 1930 } else { 1931 switch (descriptor->kind()) { 1932 case CallDescriptor::kCallCodeObject: 1933 opcode = kArchTailCallCodeObject; 1934 break; 1935 case CallDescriptor::kCallAddress: 1936 opcode = kArchTailCallAddress; 1937 break; 1938 default: 1939 UNREACHABLE(); 1940 return; 1941 } 1942 } 1943 opcode |= MiscField::encode(descriptor->flags()); 1944 1945 Emit(kArchPrepareTailCall, g.NoOutput()); 1946 1947 int first_unused_stack_slot = 1948 (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0) + 1949 stack_param_delta; 1950 buffer.instruction_args.push_back(g.TempImmediate(first_unused_stack_slot)); 1951 1952 // Emit the tailcall instruction. 1953 Emit(opcode, 0, nullptr, buffer.instruction_args.size(), 1954 &buffer.instruction_args.front(), temps.size(), 1955 temps.empty() ? nullptr : &temps.front()); 1956 } 1957 1958 1959 void InstructionSelector::VisitGoto(BasicBlock* target) { 1960 // jump to the next block. 1961 OperandGenerator g(this); 1962 Emit(kArchJmp, g.NoOutput(), g.Label(target)); 1963 } 1964 1965 void InstructionSelector::VisitReturn(Node* ret) { 1966 OperandGenerator g(this); 1967 const int input_count = linkage()->GetIncomingDescriptor()->ReturnCount() == 0 1968 ? 1 1969 : ret->op()->ValueInputCount(); 1970 DCHECK_GE(input_count, 1); 1971 auto value_locations = zone()->NewArray<InstructionOperand>(input_count); 1972 Node* pop_count = ret->InputAt(0); 1973 value_locations[0] = pop_count->opcode() == IrOpcode::kInt32Constant 1974 ? g.UseImmediate(pop_count) 1975 : g.UseRegister(pop_count); 1976 for (int i = 1; i < input_count; ++i) { 1977 value_locations[i] = 1978 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i - 1)); 1979 } 1980 Emit(kArchRet, 0, nullptr, input_count, value_locations); 1981 } 1982 1983 Instruction* InstructionSelector::EmitDeoptimize(InstructionCode opcode, 1984 InstructionOperand output, 1985 InstructionOperand a, 1986 DeoptimizeReason reason, 1987 Node* frame_state) { 1988 size_t output_count = output.IsInvalid() ? 0 : 1; 1989 InstructionOperand inputs[] = {a}; 1990 size_t input_count = arraysize(inputs); 1991 return EmitDeoptimize(opcode, output_count, &output, input_count, inputs, 1992 reason, frame_state); 1993 } 1994 1995 Instruction* InstructionSelector::EmitDeoptimize( 1996 InstructionCode opcode, InstructionOperand output, InstructionOperand a, 1997 InstructionOperand b, DeoptimizeReason reason, Node* frame_state) { 1998 size_t output_count = output.IsInvalid() ? 0 : 1; 1999 InstructionOperand inputs[] = {a, b}; 2000 size_t input_count = arraysize(inputs); 2001 return EmitDeoptimize(opcode, output_count, &output, input_count, inputs, 2002 reason, frame_state); 2003 } 2004 2005 Instruction* InstructionSelector::EmitDeoptimize( 2006 InstructionCode opcode, size_t output_count, InstructionOperand* outputs, 2007 size_t input_count, InstructionOperand* inputs, DeoptimizeReason reason, 2008 Node* frame_state) { 2009 OperandGenerator g(this); 2010 FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state); 2011 InstructionOperandVector args(instruction_zone()); 2012 args.reserve(input_count + 1 + descriptor->GetTotalSize()); 2013 for (size_t i = 0; i < input_count; ++i) { 2014 args.push_back(inputs[i]); 2015 } 2016 opcode |= MiscField::encode(static_cast<int>(input_count)); 2017 int const state_id = sequence()->AddDeoptimizationEntry(descriptor, reason); 2018 args.push_back(g.TempImmediate(state_id)); 2019 StateObjectDeduplicator deduplicator(instruction_zone()); 2020 AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator, 2021 &args, FrameStateInputKind::kAny, 2022 instruction_zone()); 2023 return Emit(opcode, output_count, outputs, args.size(), &args.front(), 0, 2024 nullptr); 2025 } 2026 2027 void InstructionSelector::EmitIdentity(Node* node) { 2028 OperandGenerator g(this); 2029 MarkAsUsed(node->InputAt(0)); 2030 SetRename(node, node->InputAt(0)); 2031 } 2032 2033 void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, 2034 DeoptimizeReason reason, 2035 Node* value) { 2036 InstructionCode opcode = kArchDeoptimize; 2037 switch (kind) { 2038 case DeoptimizeKind::kEager: 2039 opcode |= MiscField::encode(Deoptimizer::EAGER); 2040 break; 2041 case DeoptimizeKind::kSoft: 2042 opcode |= MiscField::encode(Deoptimizer::SOFT); 2043 break; 2044 } 2045 EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, reason, value); 2046 } 2047 2048 2049 void InstructionSelector::VisitThrow(Node* value) { 2050 OperandGenerator g(this); 2051 Emit(kArchThrowTerminator, g.NoOutput()); 2052 } 2053 2054 void InstructionSelector::VisitDebugBreak(Node* node) { 2055 OperandGenerator g(this); 2056 Emit(kArchDebugBreak, g.NoOutput()); 2057 } 2058 2059 void InstructionSelector::VisitComment(Node* node) { 2060 OperandGenerator g(this); 2061 InstructionOperand operand(g.UseImmediate(node)); 2062 Emit(kArchComment, 0, nullptr, 1, &operand); 2063 } 2064 2065 void InstructionSelector::VisitUnsafePointerAdd(Node* node) { 2066 #if V8_TARGET_ARCH_64_BIT 2067 VisitInt64Add(node); 2068 #else // V8_TARGET_ARCH_64_BIT 2069 VisitInt32Add(node); 2070 #endif // V8_TARGET_ARCH_64_BIT 2071 } 2072 2073 void InstructionSelector::VisitRetain(Node* node) { 2074 OperandGenerator g(this); 2075 Emit(kArchNop, g.NoOutput(), g.UseAny(node->InputAt(0))); 2076 } 2077 2078 bool InstructionSelector::CanProduceSignalingNaN(Node* node) { 2079 // TODO(jarin) Improve the heuristic here. 2080 if (node->opcode() == IrOpcode::kFloat64Add || 2081 node->opcode() == IrOpcode::kFloat64Sub || 2082 node->opcode() == IrOpcode::kFloat64Mul) { 2083 return false; 2084 } 2085 return true; 2086 } 2087 2088 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( 2089 Node* state) { 2090 DCHECK(state->opcode() == IrOpcode::kFrameState); 2091 DCHECK_EQ(kFrameStateInputCount, state->InputCount()); 2092 FrameStateInfo state_info = OpParameter<FrameStateInfo>(state); 2093 2094 int parameters = static_cast<int>( 2095 StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size()); 2096 int locals = static_cast<int>( 2097 StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size()); 2098 int stack = static_cast<int>( 2099 StateValuesAccess(state->InputAt(kFrameStateStackInput)).size()); 2100 2101 DCHECK_EQ(parameters, state_info.parameter_count()); 2102 DCHECK_EQ(locals, state_info.local_count()); 2103 2104 FrameStateDescriptor* outer_state = nullptr; 2105 Node* outer_node = state->InputAt(kFrameStateOuterStateInput); 2106 if (outer_node->opcode() == IrOpcode::kFrameState) { 2107 outer_state = GetFrameStateDescriptor(outer_node); 2108 } 2109 2110 return new (instruction_zone()) FrameStateDescriptor( 2111 instruction_zone(), state_info.type(), state_info.bailout_id(), 2112 state_info.state_combine(), parameters, locals, stack, 2113 state_info.shared_info(), outer_state); 2114 } 2115 2116 2117 } // namespace compiler 2118 } // namespace internal 2119 } // namespace v8 2120