Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/compiler/scheduler.cc

Issue 687133003: Cleanup unscheduled use count for controls of coupled nodes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/scheduler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 UNREACHABLE(); 115 UNREACHABLE();
116 break; 116 break;
117 case IrOpcode::kPhi: 117 case IrOpcode::kPhi:
118 case IrOpcode::kEffectPhi: { 118 case IrOpcode::kEffectPhi: {
119 // Phis and effect phis are coupled to their respective blocks. 119 // Phis and effect phis are coupled to their respective blocks.
120 DCHECK_EQ(Scheduler::kCoupled, data->placement_); 120 DCHECK_EQ(Scheduler::kCoupled, data->placement_);
121 DCHECK_EQ(Scheduler::kFixed, placement); 121 DCHECK_EQ(Scheduler::kFixed, placement);
122 Node* control = NodeProperties::GetControlInput(node); 122 Node* control = NodeProperties::GetControlInput(node);
123 BasicBlock* block = schedule_->block(control); 123 BasicBlock* block = schedule_->block(control);
124 schedule_->AddNode(block, node); 124 schedule_->AddNode(block, node);
125 // TODO(mstarzinger): Cheap hack to make sure unscheduled use count of
126 // control does not drop below zero. This might cause the control to be
127 // queued for scheduling more than once, which makes this ugly!
128 ++(GetData(control)->unscheduled_count_);
129 break; 125 break;
130 } 126 }
131 #define DEFINE_FLOATING_CONTROL_CASE(V) case IrOpcode::k##V: 127 #define DEFINE_FLOATING_CONTROL_CASE(V) case IrOpcode::k##V:
132 CONTROL_OP_LIST(DEFINE_FLOATING_CONTROL_CASE) 128 CONTROL_OP_LIST(DEFINE_FLOATING_CONTROL_CASE)
133 #undef DEFINE_FLOATING_CONTROL_CASE 129 #undef DEFINE_FLOATING_CONTROL_CASE
134 { 130 {
135 // Control nodes force coupled uses to be placed. 131 // Control nodes force coupled uses to be placed.
136 Node::Uses uses = node->uses(); 132 Node::Uses uses = node->uses();
137 for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) { 133 for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) {
138 if (GetPlacement(*i) == Scheduler::kCoupled) { 134 if (GetPlacement(*i) == Scheduler::kCoupled) {
139 DCHECK_EQ(node, NodeProperties::GetControlInput(*i)); 135 DCHECK_EQ(node, NodeProperties::GetControlInput(*i));
140 UpdatePlacement(*i, placement); 136 UpdatePlacement(*i, placement);
141 } 137 }
142 } 138 }
143 break; 139 break;
144 } 140 }
145 default: 141 default:
146 DCHECK_EQ(Scheduler::kSchedulable, data->placement_); 142 DCHECK_EQ(Scheduler::kSchedulable, data->placement_);
147 DCHECK_EQ(Scheduler::kScheduled, placement); 143 DCHECK_EQ(Scheduler::kScheduled, placement);
148 break; 144 break;
149 } 145 }
150 // 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
151 // 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
152 // itself can be scheduled. 148 // itself can be scheduled.
153 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { 149 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
154 // TODO(mstarzinger): Another cheap hack for use counts. 150 // TODO(mstarzinger): Another cheap hack for use counts.
155 if (GetData(*i)->placement_ == kFixed) continue; 151 if (GetData(*i)->placement_ == kFixed) continue;
156 DecrementUnscheduledUseCount(*i, i.edge().from()); 152 DecrementUnscheduledUseCount(*i, i.index(), i.edge().from());
157 } 153 }
158 } 154 }
159 data->placement_ = placement; 155 data->placement_ = placement;
160 } 156 }
161 157
162 158
163 void Scheduler::IncrementUnscheduledUseCount(Node* node, Node* from) { 159 static bool IsControlInputIndex(Node* node, int idx) {
160 return NodeProperties::FirstControlIndex(node) == idx;
161 }
162
163
164 void Scheduler::IncrementUnscheduledUseCount(Node* node, int idx, Node* from) {
titzer 2014/10/29 16:53:39 index
Michael Starzinger 2014/10/29 17:10:03 Done. Nooooo, 81 characters, the worst torture. :)
165 if (GetPlacement(from) == kCoupled && IsControlInputIndex(from, idx)) {
titzer 2014/10/29 16:55:07 What about a different predicate, IsControlInputTo
Michael Starzinger 2014/10/29 17:10:03 Done. Called it IsCoupledControlEdge() as before.
166 // Make sure that control edges from coupled nodes are not counted.
167 return;
168 }
164 if (GetPlacement(node) == kCoupled) { 169 if (GetPlacement(node) == kCoupled) {
165 // Use count for coupled nodes is summed up on their control. 170 // Use count for coupled nodes is summed up on their control.
166 Node* control = NodeProperties::GetControlInput(node); 171 Node* control = NodeProperties::GetControlInput(node);
167 return IncrementUnscheduledUseCount(control, from); 172 return IncrementUnscheduledUseCount(control, idx, from);
168 } 173 }
169 ++(GetData(node)->unscheduled_count_); 174 ++(GetData(node)->unscheduled_count_);
170 if (FLAG_trace_turbo_scheduler) { 175 if (FLAG_trace_turbo_scheduler) {
171 Trace(" Use count of #%d:%s (used by #%d:%s)++ = %d\n", node->id(), 176 Trace(" Use count of #%d:%s (used by #%d:%s)++ = %d\n", node->id(),
172 node->op()->mnemonic(), from->id(), from->op()->mnemonic(), 177 node->op()->mnemonic(), from->id(), from->op()->mnemonic(),
173 GetData(node)->unscheduled_count_); 178 GetData(node)->unscheduled_count_);
174 } 179 }
175 } 180 }
176 181
177 182
178 void Scheduler::DecrementUnscheduledUseCount(Node* node, Node* from) { 183 void Scheduler::DecrementUnscheduledUseCount(Node* node, int idx, Node* from) {
184 if (GetPlacement(from) == kCoupled && IsControlInputIndex(from, idx)) {
185 // Make sure that control edges from coupled nodes are not counted.
186 return;
187 }
179 if (GetPlacement(node) == kCoupled) { 188 if (GetPlacement(node) == kCoupled) {
180 // Use count for coupled nodes is summed up on their control. 189 // Use count for coupled nodes is summed up on their control.
181 Node* control = NodeProperties::GetControlInput(node); 190 Node* control = NodeProperties::GetControlInput(node);
182 return DecrementUnscheduledUseCount(control, from); 191 return DecrementUnscheduledUseCount(control, idx, from);
183 } 192 }
184 DCHECK(GetData(node)->unscheduled_count_ > 0); 193 DCHECK(GetData(node)->unscheduled_count_ > 0);
185 --(GetData(node)->unscheduled_count_); 194 --(GetData(node)->unscheduled_count_);
186 if (FLAG_trace_turbo_scheduler) { 195 if (FLAG_trace_turbo_scheduler) {
187 Trace(" Use count of #%d:%s (used by #%d:%s)-- = %d\n", node->id(), 196 Trace(" Use count of #%d:%s (used by #%d:%s)-- = %d\n", node->id(),
188 node->op()->mnemonic(), from->id(), from->op()->mnemonic(), 197 node->op()->mnemonic(), from->id(), from->op()->mnemonic(),
189 GetData(node)->unscheduled_count_); 198 GetData(node)->unscheduled_count_);
190 } 199 }
191 if (GetData(node)->unscheduled_count_ == 0) { 200 if (GetData(node)->unscheduled_count_ == 0) {
192 Trace(" newly eligible #%d:%s\n", node->id(), node->op()->mnemonic()); 201 Trace(" newly eligible #%d:%s\n", node->id(), node->op()->mnemonic());
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 DCHECK(block != NULL); 1012 DCHECK(block != NULL);
1004 schedule_->AddNode(block, node); 1013 schedule_->AddNode(block, node);
1005 } 1014 }
1006 } 1015 }
1007 1016
1008 return GenericGraphVisit::CONTINUE; 1017 return GenericGraphVisit::CONTINUE;
1009 } 1018 }
1010 1019
1011 void PostEdge(Node* from, int index, Node* to) { 1020 void PostEdge(Node* from, int index, Node* to) {
1012 // If the edge is from an unscheduled node, then tally it in the use count 1021 // If the edge is from an unscheduled node, then tally it in the use count
1013 // for all of its inputs. Also make sure that control edges from coupled 1022 // for all of its inputs. The same criterion will be used in ScheduleLate
1014 // nodes are not counted. The same criterion will be used in ScheduleLate
1015 // for decrementing use counts. 1023 // for decrementing use counts.
1016 if (!schedule_->IsScheduled(from) && !IsCoupledControlEdge(from, index)) { 1024 if (!schedule_->IsScheduled(from)) {
1017 DCHECK_NE(Scheduler::kFixed, scheduler_->GetPlacement(from)); 1025 DCHECK_NE(Scheduler::kFixed, scheduler_->GetPlacement(from));
1018 scheduler_->IncrementUnscheduledUseCount(to, from); 1026 scheduler_->IncrementUnscheduledUseCount(to, index, from);
1019 } 1027 }
1020 } 1028 }
1021 1029
1022 bool IsCoupledControlEdge(Node* node, int index) {
1023 return scheduler_->GetPlacement(node) == Scheduler::kCoupled &&
1024 NodeProperties::FirstControlIndex(node) == index;
1025 }
1026
1027 private: 1030 private:
1028 Scheduler* scheduler_; 1031 Scheduler* scheduler_;
1029 Schedule* schedule_; 1032 Schedule* schedule_;
1030 }; 1033 };
1031 1034
1032 1035
1033 void Scheduler::PrepareUses() { 1036 void Scheduler::PrepareUses() {
1034 Trace("--- PREPARE USES -------------------------------------------\n"); 1037 Trace("--- PREPARE USES -------------------------------------------\n");
1035 1038
1036 // Count the uses of every node, it will be used to ensure that all of a 1039 // Count the uses of every node, it will be used to ensure that all of a
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { 1359 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) {
1357 schedule_->SetBlockForNode(to, *i); 1360 schedule_->SetBlockForNode(to, *i);
1358 scheduled_nodes_[to->id().ToSize()].push_back(*i); 1361 scheduled_nodes_[to->id().ToSize()].push_back(*i);
1359 } 1362 }
1360 nodes->clear(); 1363 nodes->clear();
1361 } 1364 }
1362 1365
1363 } // namespace compiler 1366 } // namespace compiler
1364 } // namespace internal 1367 } // namespace internal
1365 } // namespace v8 1368 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/scheduler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698