| 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 |