Lines Matching defs:node

33 // A target is a fallthrough of a control node if its ID is the next ID
34 // after the control node.
37 bool IsTargetOfNodeFallthrough(ControlNode* node, BasicBlock* target) {
38 return node->id() + 1 == target->first_id();
41 ControlNode* NearestPostDominatingHole(ControlNode* node) {
43 // post-dominating hole is the conditional control node's next post-dominating
45 if (node->Is<ConditionalControlNode>()) {
46 return node->next_post_dominating_hole();
49 // If the node is a Jump, it may be a hole, but only if it is not a
52 if (Jump* jump = node->TryCast<Jump>()) {
58 return node;
61 bool IsLiveAtTarget(ValueNode* node, ControlNode* source, BasicBlock* target) {
62 DCHECK_NOT_NULL(node);
63 DCHECK(!node->is_dead());
68 return node->id() < target->FirstNonGapMoveId();
72 // DCHECK_GT(node->next_use, source->id());
75 return node->live_range().end >= target->first_id();
108 // that we will unconditionally reach on our way to an exit node. Such
155 if (auto node = control->TryCast<Jump>()) {
156 // If the current control node is a jump, prepend it to the list of jumps
159 NearestPostDominatingHole(node->target()->control_node()));
160 } else if (auto node = control->TryCast<ConditionalControlNode>()) {
162 NearestPostDominatingHole(node->if_true()->control_node());
164 NearestPostDominatingHole(node->if_false()->control_node());
167 // control-node of the longest branch after the last node of the shortest
176 // reachable control-node of the longest branch (the second control
177 // node).
192 // the control node.
201 ValueNode* node = GetRegisterValue(reg);
207 printing_visitor_->os() << reg << "=v" << node->id();
311 ValueNode* node, InputLocation* input_location) {
312 DCHECK(!node->is_dead());
315 node->set_next_use(input_location->next_use_id());
317 if (!node->is_dead()) return;
320 FreeRegisters(node);
329 *compilation_unit_, [&](ValueNode* node, interpreter::Register reg) {
331 input->InjectAllocated(node->allocation());
332 UpdateUse(node, input);
342 *compilation_unit_, [&](ValueNode* node, interpreter::Register reg) {
346 input->InjectAllocated(node->allocation());
347 UpdateUse(node, input);
351 void StraightForwardRegisterAllocator::AllocateNode(Node* node) {
352 for (Input& input : *node) AssignInput(input);
353 AssignTemporaries(node);
354 if (node->properties().can_eager_deopt()) {
355 UpdateUse(*node->eager_deopt_info());
357 for (Input& input : *node) UpdateUse(&input);
359 if (node->properties().is_call()) SpillAndClearRegisters();
361 // Allocate node output.
362 if (node->Is<ValueNode>()) AllocateNodeResult(node->Cast<ValueNode>());
364 // Lazy deopts are semantically after the node, so update them last.
365 if (node->properties().can_lazy_deopt()) {
366 UpdateUse(*node->lazy_deopt_info());
370 printing_visitor_->Process(node,
378 void StraightForwardRegisterAllocator::AllocateNodeResult(ValueNode* node) {
379 DCHECK(!node->Is<Phi>());
381 node->SetNoSpillOrHint();
384 compiler::UnallocatedOperand::cast(node->result().operand());
387 DCHECK(node->Is<InitialValue>());
393 node->result().SetAllocated(location);
394 node->Spill(location);
401 node->result().SetAllocated(ForceAllocate(r, node));
406 node->result().SetAllocated(AllocateRegister(node));
410 Input& input = node->input(operand.input_index());
412 node->result().SetAllocated(ForceAllocate(r, node));
424 // Immediately kill the register use if the node doesn't have a valid
427 if (!node->has_valid_live_range() &&
428 node->result().operand().IsAnyRegister()) {
429 DCHECK(node->has_register());
430 FreeRegisters(node);
431 DCHECK(!node->has_register());
432 DCHECK(node->is_dead());
440 ValueNode* node = GetRegisterValue(reg);
442 // Remove the register from the node's list.
443 node->RemoveRegister(reg);
446 if (node->has_register() || node->is_spilled()) return;
451 SetRegister(target_reg, node);
462 << "gap move: " << PrintNodeLabel(graph_labeller(), node) << ": "
470 Spill(node);
490 ValueNode* node = GetRegisterValue(reg);
491 if (!IsLiveAtTarget(node, control_node, target)) {
492 FreeRegisters(node);
493 // Update the registers we're visiting to avoid revisiting this node.
499 void StraightForwardRegisterAllocator::AllocateControlNode(ControlNode* node,
501 for (Input& input : *node) AssignInput(input);
502 AssignTemporaries(node);
503 if (node->properties().can_eager_deopt()) {
504 UpdateUse(*node->eager_deopt_info());
506 for (Input& input : *node) UpdateUse(&input);
508 if (node->properties().is_call()) SpillAndClearRegisters();
511 if (auto unconditional = node->TryCast<UnconditionalControlNode>()) {
517 input.InjectAllocated(input.node()->allocation());
524 if (node->properties().can_eager_deopt()) SpillRegisters();
528 if (auto unconditional = node->TryCast<UnconditionalControlNode>()) {
534 } else if (auto conditional = node->TryCast<ConditionalControlNode>()) {
540 printing_visitor_->Process(node,
572 // We're at the control node, so append instead.
581 void StraightForwardRegisterAllocator::Spill(ValueNode* node) {
582 if (node->is_spilled()) return;
583 AllocateSpillSlot(node);
586 << "spill: " << node->spill_slot() << " ← "
587 << PrintNodeLabel(graph_labeller(), node) << std::endl;
594 ValueNode* node = input.node();
595 compiler::AllocatedOperand location = node->allocation();
605 input.SetAllocated(ForceAllocate(reg, node));
613 input.SetAllocated(AllocateRegister(node));
637 ValueNode* node = GetRegisterValue(reg);
638 Spill(node);
645 ValueNode* node = GetRegisterValue(reg);
646 Spill(node);
647 FreeRegisters(node);
652 void StraightForwardRegisterAllocator::AllocateSpillSlot(ValueNode* node) {
653 DCHECK(!node->is_spilled());
655 compilation_unit_->push_stack_value_repr(node->value_representation());
656 node->Spill(compiler::AllocatedOperand(compiler::AllocatedOperand::STACK_SLOT,
684 ValueNode* node) {
686 compiler::InstructionOperand allocation = TryAllocateRegister(node);
692 Register reg, ValueNode* node) {
696 } else if (GetRegisterValue(reg) == node) {
706 SetRegister(reg, node);
712 ValueNode* node) {
714 register_values_[reg.code()] = node;
715 node->AddRegister(reg);
719 StraightForwardRegisterAllocator::TryAllocateRegister(ValueNode* node) {
725 SetRegister(reg, node);
730 void StraightForwardRegisterAllocator::AssignTemporaries(NodeBase* node) {
731 int num_temporaries_needed = node->num_temporaries_needed();
740 node->assign_temporaries(free_registers_);
748 ValueNode* node = GetRegisterValue(reg);
749 FreeRegisters(node);
760 ValueNode* node;
762 LoadMergeState(entry.state, &node, &merge);
763 if (node != nullptr) {
765 SetRegister(reg, node);
777 ValueNode* node;
779 LoadMergeState(entry.state, &node, &merge);
780 if (node == incoming) found = true;
792 ValueNode* node = nullptr;
794 node = GetRegisterValue(reg);
795 if (!IsLiveAtTarget(node, source, target)) node = nullptr;
797 entry.state = {node, initialized_node};
814 ValueNode* node;
816 LoadMergeState(entry.state, &node, &merge);
830 if (incoming == node) {
838 // The register is already occupied with a different node. Figure out
839 // where that node is allocated on the incoming branch.
840 merge->operand(predecessor_id) = node->allocation();
850 DCHECK_IMPLIES(node == nullptr, incoming != nullptr);
851 if (node == nullptr && !incoming->is_spilled()) {
863 merge->node = node == nullptr ? incoming : node;
867 // branches agree that the current node is in the register info.
869 node == nullptr
880 // incoming value. Otherwise find the merge-point node in the incoming
882 if (node == nullptr) {
885 merge->operand(predecessor_id) = node->allocation();