v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
linear-scheduler.cc
Go to the documentation of this file.
1// Copyright 2013 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
6
8#include "src/compiler/node.h"
11
12namespace v8 {
13namespace internal {
14namespace compiler {
15
17 : graph_(graph), control_level_(zone), early_schedule_position_(zone) {
19}
20
22 Node* start = graph_->start();
24
25 // Do BFS from the start node and compute the level of
26 // each control node.
27 std::queue<Node*> queue({start});
28 while (!queue.empty()) {
29 Node* node = queue.front();
30 int level = GetControlLevel(node);
31 queue.pop();
32 for (Edge const edge : node->use_edges()) {
33 if (!NodeProperties::IsControlEdge(edge)) continue;
34 Node* use = edge.from();
35 if (use->opcode() == IrOpcode::kLoopExit &&
36 node->opcode() == IrOpcode::kLoop)
37 continue;
38 if (control_level_.find(use) == control_level_.end() &&
39 use->opcode() != IrOpcode::kEnd) {
40 SetControlLevel(use, level + 1);
41 queue.push(use);
42 }
43 }
44 }
45}
46
49
50 auto it = early_schedule_position_.find(node);
51 if (it != early_schedule_position_.end()) return it->second;
52
53 std::stack<NodeState> stack;
54 stack.push({node, nullptr, 0});
55 Node* early_schedule_position = nullptr;
56 while (!stack.empty()) {
57 NodeState& top = stack.top();
58 if (NodeProperties::IsPhi(top.node)) {
59 // For phi node, the early schedule position is its control node.
60 early_schedule_position = NodeProperties::GetControlInput(top.node);
61 } else if (top.node->InputCount() == 0) {
62 // For node without inputs, the early schedule position is start node.
63 early_schedule_position = graph_->start();
64 } else {
65 // For others, the early schedule position is one of its inputs' early
66 // schedule position with maximal level.
67 if (top.input_index == top.node->InputCount()) {
68 // All inputs are visited, set early schedule position.
69 early_schedule_position = top.early_schedule_position;
70 } else {
71 // Visit top's input and find its early schedule position.
72 Node* input = top.node->InputAt(top.input_index);
73 Node* input_early_schedule_position = nullptr;
74 if (NodeProperties::IsControl(input)) {
75 input_early_schedule_position = input;
76 } else {
77 auto early_pos_it = early_schedule_position_.find(input);
78 if (early_pos_it != early_schedule_position_.end()) {
79 input_early_schedule_position = early_pos_it->second;
80 }
81 }
82 if (input_early_schedule_position != nullptr) {
83 if (top.early_schedule_position == nullptr ||
84 GetControlLevel(top.early_schedule_position) <
85 GetControlLevel(input_early_schedule_position)) {
86 top.early_schedule_position = input_early_schedule_position;
87 }
88 top.input_index += 1;
89 } else {
90 top.input_index += 1;
91 stack.push({input, nullptr, 0});
92 }
93 continue;
94 }
95 }
96
97 // Found top's early schedule position, set it to the cache and pop it out
98 // of the stack.
99 SetEarlySchedulePosition(top.node, early_schedule_position);
100 stack.pop();
101 // Update early schedule position of top's use.
102 if (!stack.empty()) {
103 NodeState& use = stack.top();
104 if (use.early_schedule_position == nullptr ||
105 GetControlLevel(use.early_schedule_position) <
106 GetControlLevel(early_schedule_position)) {
107 use.early_schedule_position = early_schedule_position;
108 }
109 }
110 }
111
112 DCHECK(early_schedule_position != nullptr);
113 return early_schedule_position;
114}
115
117 Node* early_schedule_position0 = NodeProperties::IsControl(node0)
118 ? node0
120 Node* early_schedule_position1 = NodeProperties::IsControl(node1)
121 ? node1
123 return early_schedule_position0 == early_schedule_position1;
124}
125
126} // namespace compiler
127} // namespace internal
128} // namespace v8
LinearScheduler(Zone *zone, TFGraph *graph)
void SetEarlySchedulePosition(Node *node, Node *early_schedule_position)
void SetControlLevel(Node *control, int level)
bool SameBasicBlock(Node *node0, Node *node1)
ZoneMap< Node *, Node * > early_schedule_position_
static Node * GetControlInput(Node *node, int index=0)
Node * InputAt(int index) const
Definition node.h:70
int start
Node * node
ZoneStack< RpoNumber > & stack
#define DCHECK(condition)
Definition logging.h:482
TFGraph * graph_