OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <deque> | 5 #include <deque> |
6 #include <queue> | 6 #include <queue> |
7 | 7 |
8 #include "src/compiler/scheduler.h" | 8 #include "src/compiler/scheduler.h" |
9 | 9 |
10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 } | 140 } |
141 default: | 141 default: |
142 DCHECK_EQ(Scheduler::kSchedulable, data->placement_); | 142 DCHECK_EQ(Scheduler::kSchedulable, data->placement_); |
143 DCHECK_EQ(Scheduler::kScheduled, placement); | 143 DCHECK_EQ(Scheduler::kScheduled, placement); |
144 break; | 144 break; |
145 } | 145 } |
146 // Reduce the use count of the node's inputs to potentially make them | 146 // Reduce the use count of the node's inputs to potentially make them |
147 // schedulable. If all the uses of a node have been scheduled, then the node | 147 // schedulable. If all the uses of a node have been scheduled, then the node |
148 // itself can be scheduled. | 148 // itself can be scheduled. |
149 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { | 149 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { |
150 // TODO(mstarzinger): Another cheap hack for use counts. | |
151 if (GetData(*i)->placement_ == kFixed) continue; | |
152 DecrementUnscheduledUseCount(*i, i.index(), i.edge().from()); | 150 DecrementUnscheduledUseCount(*i, i.index(), i.edge().from()); |
153 } | 151 } |
154 } | 152 } |
155 data->placement_ = placement; | 153 data->placement_ = placement; |
156 } | 154 } |
157 | 155 |
158 | 156 |
159 bool Scheduler::IsCoupledControlEdge(Node* node, int index) { | 157 bool Scheduler::IsCoupledControlEdge(Node* node, int index) { |
160 return GetPlacement(node) == kCoupled && | 158 return GetPlacement(node) == kCoupled && |
161 NodeProperties::FirstControlIndex(node) == index; | 159 NodeProperties::FirstControlIndex(node) == index; |
162 } | 160 } |
163 | 161 |
164 | 162 |
165 void Scheduler::IncrementUnscheduledUseCount(Node* node, int index, | 163 void Scheduler::IncrementUnscheduledUseCount(Node* node, int index, |
166 Node* from) { | 164 Node* from) { |
167 // Make sure that control edges from coupled nodes are not counted. | 165 // Make sure that control edges from coupled nodes are not counted. |
168 if (IsCoupledControlEdge(from, index)) return; | 166 if (IsCoupledControlEdge(from, index)) return; |
169 | 167 |
| 168 // Tracking use counts for fixed nodes is useless. |
| 169 if (GetPlacement(node) == kFixed) return; |
| 170 |
170 // Use count for coupled nodes is summed up on their control. | 171 // Use count for coupled nodes is summed up on their control. |
171 if (GetPlacement(node) == kCoupled) { | 172 if (GetPlacement(node) == kCoupled) { |
172 Node* control = NodeProperties::GetControlInput(node); | 173 Node* control = NodeProperties::GetControlInput(node); |
173 return IncrementUnscheduledUseCount(control, index, from); | 174 return IncrementUnscheduledUseCount(control, index, from); |
174 } | 175 } |
175 | 176 |
176 ++(GetData(node)->unscheduled_count_); | 177 ++(GetData(node)->unscheduled_count_); |
177 if (FLAG_trace_turbo_scheduler) { | 178 if (FLAG_trace_turbo_scheduler) { |
178 Trace(" Use count of #%d:%s (used by #%d:%s)++ = %d\n", node->id(), | 179 Trace(" Use count of #%d:%s (used by #%d:%s)++ = %d\n", node->id(), |
179 node->op()->mnemonic(), from->id(), from->op()->mnemonic(), | 180 node->op()->mnemonic(), from->id(), from->op()->mnemonic(), |
180 GetData(node)->unscheduled_count_); | 181 GetData(node)->unscheduled_count_); |
181 } | 182 } |
182 } | 183 } |
183 | 184 |
184 | 185 |
185 void Scheduler::DecrementUnscheduledUseCount(Node* node, int index, | 186 void Scheduler::DecrementUnscheduledUseCount(Node* node, int index, |
186 Node* from) { | 187 Node* from) { |
187 // Make sure that control edges from coupled nodes are not counted. | 188 // Make sure that control edges from coupled nodes are not counted. |
188 if (IsCoupledControlEdge(from, index)) return; | 189 if (IsCoupledControlEdge(from, index)) return; |
189 | 190 |
| 191 // Tracking use counts for fixed nodes is useless. |
| 192 if (GetPlacement(node) == kFixed) return; |
| 193 |
190 // Use count for coupled nodes is summed up on their control. | 194 // Use count for coupled nodes is summed up on their control. |
191 if (GetPlacement(node) == kCoupled) { | 195 if (GetPlacement(node) == kCoupled) { |
192 Node* control = NodeProperties::GetControlInput(node); | 196 Node* control = NodeProperties::GetControlInput(node); |
193 return DecrementUnscheduledUseCount(control, index, from); | 197 return DecrementUnscheduledUseCount(control, index, from); |
194 } | 198 } |
195 | 199 |
196 DCHECK(GetData(node)->unscheduled_count_ > 0); | 200 DCHECK(GetData(node)->unscheduled_count_ > 0); |
197 --(GetData(node)->unscheduled_count_); | 201 --(GetData(node)->unscheduled_count_); |
198 if (FLAG_trace_turbo_scheduler) { | 202 if (FLAG_trace_turbo_scheduler) { |
199 Trace(" Use count of #%d:%s (used by #%d:%s)-- = %d\n", node->id(), | 203 Trace(" Use count of #%d:%s (used by #%d:%s)-- = %d\n", node->id(), |
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 public: | 1011 public: |
1008 explicit PrepareUsesVisitor(Scheduler* scheduler) | 1012 explicit PrepareUsesVisitor(Scheduler* scheduler) |
1009 : scheduler_(scheduler), schedule_(scheduler->schedule_) {} | 1013 : scheduler_(scheduler), schedule_(scheduler->schedule_) {} |
1010 | 1014 |
1011 GenericGraphVisit::Control Pre(Node* node) { | 1015 GenericGraphVisit::Control Pre(Node* node) { |
1012 if (scheduler_->GetPlacement(node) == Scheduler::kFixed) { | 1016 if (scheduler_->GetPlacement(node) == Scheduler::kFixed) { |
1013 // Fixed nodes are always roots for schedule late. | 1017 // Fixed nodes are always roots for schedule late. |
1014 scheduler_->schedule_root_nodes_.push_back(node); | 1018 scheduler_->schedule_root_nodes_.push_back(node); |
1015 if (!schedule_->IsScheduled(node)) { | 1019 if (!schedule_->IsScheduled(node)) { |
1016 // Make sure root nodes are scheduled in their respective blocks. | 1020 // Make sure root nodes are scheduled in their respective blocks. |
1017 Trace(" Scheduling fixed position node #%d:%s\n", node->id(), | 1021 Trace("Scheduling fixed position node #%d:%s\n", node->id(), |
1018 node->op()->mnemonic()); | 1022 node->op()->mnemonic()); |
1019 IrOpcode::Value opcode = node->opcode(); | 1023 IrOpcode::Value opcode = node->opcode(); |
1020 BasicBlock* block = | 1024 BasicBlock* block = |
1021 opcode == IrOpcode::kParameter | 1025 opcode == IrOpcode::kParameter |
1022 ? schedule_->start() | 1026 ? schedule_->start() |
1023 : schedule_->block(NodeProperties::GetControlInput(node)); | 1027 : schedule_->block(NodeProperties::GetControlInput(node)); |
1024 DCHECK(block != NULL); | 1028 DCHECK(block != NULL); |
1025 schedule_->AddNode(block, node); | 1029 schedule_->AddNode(block, node); |
1026 } | 1030 } |
1027 } | 1031 } |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { | 1375 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { |
1372 schedule_->SetBlockForNode(to, *i); | 1376 schedule_->SetBlockForNode(to, *i); |
1373 scheduled_nodes_[to->id().ToSize()].push_back(*i); | 1377 scheduled_nodes_[to->id().ToSize()].push_back(*i); |
1374 } | 1378 } |
1375 nodes->clear(); | 1379 nodes->clear(); |
1376 } | 1380 } |
1377 | 1381 |
1378 } // namespace compiler | 1382 } // namespace compiler |
1379 } // namespace internal | 1383 } // namespace internal |
1380 } // namespace v8 | 1384 } // namespace v8 |
OLD | NEW |