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/schedule.h

Issue 499363002: Schedule floating control. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 months 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/pipeline.cc ('k') | src/compiler/scheduler.h » ('j') | 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 #ifndef V8_COMPILER_SCHEDULE_H_ 5 #ifndef V8_COMPILER_SCHEDULE_H_
6 #define V8_COMPILER_SCHEDULE_H_ 6 #define V8_COMPILER_SCHEDULE_H_
7 7
8 #include <vector> 8 #include <vector>
9 9
10 #include "src/v8.h" 10 #include "src/v8.h"
(...skipping 22 matching lines...) Expand all
33 kNone, // Control not initialized yet. 33 kNone, // Control not initialized yet.
34 kGoto, // Goto a single successor block. 34 kGoto, // Goto a single successor block.
35 kBranch, // Branch if true to first successor, otherwise second. 35 kBranch, // Branch if true to first successor, otherwise second.
36 kReturn, // Return a value from this method. 36 kReturn, // Return a value from this method.
37 kThrow, // Throw an exception. 37 kThrow, // Throw an exception.
38 kCall, // Call to a possibly deoptimizing or throwing function. 38 kCall, // Call to a possibly deoptimizing or throwing function.
39 kDeoptimize // Deoptimize. 39 kDeoptimize // Deoptimize.
40 }; 40 };
41 41
42 int32_t rpo_number_; // special RPO number of the block. 42 int32_t rpo_number_; // special RPO number of the block.
43 BasicBlock* dominator_; // Immediate dominator of the block.
43 BasicBlock* loop_header_; // Pointer to dominating loop header basic block, 44 BasicBlock* loop_header_; // Pointer to dominating loop header basic block,
44 // NULL if none. For loop headers, this points to 45 // NULL if none. For loop headers, this points to
45 // enclosing loop header. 46 // enclosing loop header.
46 int32_t loop_depth_; // loop nesting, 0 is top-level 47 int32_t loop_depth_; // loop nesting, 0 is top-level
47 int32_t loop_end_; // end of the loop, if this block is a loop header. 48 int32_t loop_end_; // end of the loop, if this block is a loop header.
48 int32_t code_start_; // start index of arch-specific code. 49 int32_t code_start_; // start index of arch-specific code.
49 int32_t code_end_; // end index of arch-specific code. 50 int32_t code_end_; // end index of arch-specific code.
50 bool deferred_; // {true} if this block is considered the slow 51 bool deferred_; // {true} if this block is considered the slow
51 // path. 52 // path.
52 Control control_; // Control at the end of the block. 53 Control control_; // Control at the end of the block.
53 Node* control_input_; // Input value for control. 54 Node* control_input_; // Input value for control.
54 NodeVector nodes_; // nodes of this block in forward order. 55 NodeVector nodes_; // nodes of this block in forward order.
55 56
56 explicit BasicBlockData(Zone* zone) 57 explicit BasicBlockData(Zone* zone)
57 : rpo_number_(-1), 58 : rpo_number_(-1),
59 dominator_(NULL),
58 loop_header_(NULL), 60 loop_header_(NULL),
59 loop_depth_(0), 61 loop_depth_(0),
60 loop_end_(-1), 62 loop_end_(-1),
61 code_start_(-1), 63 code_start_(-1),
62 code_end_(-1), 64 code_end_(-1),
63 deferred_(false), 65 deferred_(false),
64 control_(kNone), 66 control_(kNone),
65 control_input_(NULL), 67 control_input_(NULL),
66 nodes_(zone) {} 68 nodes_(zone) {}
67 69
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // and ordering them within basic blocks. Prior to computing a schedule, 155 // and ordering them within basic blocks. Prior to computing a schedule,
154 // a graph has no notion of control flow ordering other than that induced 156 // a graph has no notion of control flow ordering other than that induced
155 // by the graph's dependencies. A schedule is required to generate code. 157 // by the graph's dependencies. A schedule is required to generate code.
156 class Schedule : public GenericGraph<BasicBlock> { 158 class Schedule : public GenericGraph<BasicBlock> {
157 public: 159 public:
158 explicit Schedule(Zone* zone) 160 explicit Schedule(Zone* zone)
159 : GenericGraph<BasicBlock>(zone), 161 : GenericGraph<BasicBlock>(zone),
160 zone_(zone), 162 zone_(zone),
161 all_blocks_(zone), 163 all_blocks_(zone),
162 nodeid_to_block_(zone), 164 nodeid_to_block_(zone),
163 rpo_order_(zone), 165 rpo_order_(zone) {
164 immediate_dominator_(zone) {
165 SetStart(NewBasicBlock()); // entry. 166 SetStart(NewBasicBlock()); // entry.
166 SetEnd(NewBasicBlock()); // exit. 167 SetEnd(NewBasicBlock()); // exit.
167 } 168 }
168 169
169 // Return the block which contains {node}, if any. 170 // Return the block which contains {node}, if any.
170 BasicBlock* block(Node* node) const { 171 BasicBlock* block(Node* node) const {
171 if (node->id() < static_cast<NodeId>(nodeid_to_block_.size())) { 172 if (node->id() < static_cast<NodeId>(nodeid_to_block_.size())) {
172 return nodeid_to_block_[node->id()]; 173 return nodeid_to_block_[node->id()];
173 } 174 }
174 return NULL; 175 return NULL;
175 } 176 }
176 177
177 BasicBlock* dominator(BasicBlock* block) {
178 return immediate_dominator_[block->id()];
179 }
180
181 bool IsScheduled(Node* node) { 178 bool IsScheduled(Node* node) {
182 int length = static_cast<int>(nodeid_to_block_.size()); 179 int length = static_cast<int>(nodeid_to_block_.size());
183 if (node->id() >= length) return false; 180 if (node->id() >= length) return false;
184 return nodeid_to_block_[node->id()] != NULL; 181 return nodeid_to_block_[node->id()] != NULL;
185 } 182 }
186 183
187 BasicBlock* GetBlockById(int block_id) { return all_blocks_[block_id]; } 184 BasicBlock* GetBlockById(int block_id) { return all_blocks_[block_id]; }
188 185
189 int BasicBlockCount() const { return NodeCount(); } 186 int BasicBlockCount() const { return NodeCount(); }
190 int RpoBlockCount() const { return static_cast<int>(rpo_order_.size()); } 187 int RpoBlockCount() const { return static_cast<int>(rpo_order_.size()); }
(...skipping 14 matching lines...) Expand all
205 BasicBlock* block = 202 BasicBlock* block =
206 BasicBlock::New(this, 0, static_cast<BasicBlock**>(NULL)); 203 BasicBlock::New(this, 0, static_cast<BasicBlock**>(NULL));
207 all_blocks_.push_back(block); 204 all_blocks_.push_back(block);
208 return block; 205 return block;
209 } 206 }
210 207
211 // BasicBlock building: records that a node will later be added to a block but 208 // BasicBlock building: records that a node will later be added to a block but
212 // doesn't actually add the node to the block. 209 // doesn't actually add the node to the block.
213 inline void PlanNode(BasicBlock* block, Node* node) { 210 inline void PlanNode(BasicBlock* block, Node* node) {
214 if (FLAG_trace_turbo_scheduler) { 211 if (FLAG_trace_turbo_scheduler) {
215 PrintF("Planning node %d for future add to block %d\n", node->id(), 212 PrintF("Planning #%d:%s for future add to B%d\n", node->id(),
216 block->id()); 213 node->op()->mnemonic(), block->id());
217 } 214 }
218 DCHECK(this->block(node) == NULL); 215 DCHECK(this->block(node) == NULL);
219 SetBlockForNode(block, node); 216 SetBlockForNode(block, node);
220 } 217 }
221 218
222 // BasicBlock building: add a node to the end of the block. 219 // BasicBlock building: add a node to the end of the block.
223 inline void AddNode(BasicBlock* block, Node* node) { 220 inline void AddNode(BasicBlock* block, Node* node) {
224 if (FLAG_trace_turbo_scheduler) { 221 if (FLAG_trace_turbo_scheduler) {
225 PrintF("Adding node %d to block %d\n", node->id(), block->id()); 222 PrintF("Adding #%d:%s to B%d\n", node->id(), node->op()->mnemonic(),
223 block->id());
226 } 224 }
227 DCHECK(this->block(node) == NULL || this->block(node) == block); 225 DCHECK(this->block(node) == NULL || this->block(node) == block);
228 block->nodes_.push_back(node); 226 block->nodes_.push_back(node);
229 SetBlockForNode(block, node); 227 SetBlockForNode(block, node);
230 } 228 }
231 229
232 // BasicBlock building: add a goto to the end of {block}. 230 // BasicBlock building: add a goto to the end of {block}.
233 void AddGoto(BasicBlock* block, BasicBlock* succ) { 231 void AddGoto(BasicBlock* block, BasicBlock* succ) {
234 DCHECK(block->control_ == BasicBlock::kNone); 232 DCHECK(block->control_ == BasicBlock::kNone);
235 block->control_ = BasicBlock::kGoto; 233 block->control_ = BasicBlock::kGoto;
236 AddSuccessor(block, succ); 234 AddSuccessor(block, succ);
237 } 235 }
238 236
239 // BasicBlock building: add a (branching) call at the end of {block}. 237 // BasicBlock building: add a (branching) call at the end of {block}.
240 void AddCall(BasicBlock* block, Node* call, BasicBlock* cont_block, 238 void AddCall(BasicBlock* block, Node* call, BasicBlock* cont_block,
241 BasicBlock* deopt_block) { 239 BasicBlock* deopt_block) {
242 DCHECK(block->control_ == BasicBlock::kNone); 240 DCHECK(block->control_ == BasicBlock::kNone);
243 DCHECK(call->opcode() == IrOpcode::kCall); 241 DCHECK(call->opcode() == IrOpcode::kCall);
244 block->control_ = BasicBlock::kCall; 242 block->control_ = BasicBlock::kCall;
245 // Insert the deopt block first so that the RPO order builder picks 243 // Insert the deopt block first so that the RPO order builder picks
246 // it first (and thus it ends up late in the RPO order). 244 // it first (and thus it ends up late in the RPO order).
247 AddSuccessor(block, deopt_block); 245 AddSuccessor(block, deopt_block);
248 AddSuccessor(block, cont_block); 246 AddSuccessor(block, cont_block);
249 SetControlInput(block, call); 247 SetControlInput(block, call);
248 SetBlockForNode(block, call);
250 } 249 }
251 250
252 // BasicBlock building: add a branch at the end of {block}. 251 // BasicBlock building: add a branch at the end of {block}.
253 void AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock, 252 void AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
254 BasicBlock* fblock) { 253 BasicBlock* fblock) {
255 DCHECK(block->control_ == BasicBlock::kNone); 254 DCHECK(block->control_ == BasicBlock::kNone);
256 DCHECK(branch->opcode() == IrOpcode::kBranch); 255 DCHECK(branch->opcode() == IrOpcode::kBranch);
257 block->control_ = BasicBlock::kBranch; 256 block->control_ = BasicBlock::kBranch;
258 AddSuccessor(block, tblock); 257 AddSuccessor(block, tblock);
259 AddSuccessor(block, fblock); 258 AddSuccessor(block, fblock);
260 SetControlInput(block, branch); 259 SetControlInput(block, branch);
260 if (branch->opcode() == IrOpcode::kBranch) {
261 // TODO(titzer): require a Branch node here. (sloppy tests).
262 SetBlockForNode(block, branch);
263 }
261 } 264 }
262 265
263 // BasicBlock building: add a return at the end of {block}. 266 // BasicBlock building: add a return at the end of {block}.
264 void AddReturn(BasicBlock* block, Node* input) { 267 void AddReturn(BasicBlock* block, Node* input) {
265 // TODO(titzer): require a Return node here.
266 DCHECK(block->control_ == BasicBlock::kNone); 268 DCHECK(block->control_ == BasicBlock::kNone);
267 block->control_ = BasicBlock::kReturn; 269 block->control_ = BasicBlock::kReturn;
268 SetControlInput(block, input); 270 SetControlInput(block, input);
269 if (block != end()) AddSuccessor(block, end()); 271 if (block != end()) AddSuccessor(block, end());
272 if (input->opcode() == IrOpcode::kReturn) {
273 // TODO(titzer): require a Return node here. (sloppy tests).
274 SetBlockForNode(block, input);
275 }
270 } 276 }
271 277
272 // BasicBlock building: add a throw at the end of {block}. 278 // BasicBlock building: add a throw at the end of {block}.
273 void AddThrow(BasicBlock* block, Node* input) { 279 void AddThrow(BasicBlock* block, Node* input) {
274 DCHECK(block->control_ == BasicBlock::kNone); 280 DCHECK(block->control_ == BasicBlock::kNone);
275 block->control_ = BasicBlock::kThrow; 281 block->control_ = BasicBlock::kThrow;
276 SetControlInput(block, input); 282 SetControlInput(block, input);
277 if (block != end()) AddSuccessor(block, end()); 283 if (block != end()) AddSuccessor(block, end());
278 } 284 }
279 285
(...skipping 28 matching lines...) Expand all
308 if (node->id() >= length) { 314 if (node->id() >= length) {
309 nodeid_to_block_.resize(node->id() + 1); 315 nodeid_to_block_.resize(node->id() + 1);
310 } 316 }
311 nodeid_to_block_[node->id()] = block; 317 nodeid_to_block_[node->id()] = block;
312 } 318 }
313 319
314 Zone* zone_; 320 Zone* zone_;
315 BasicBlockVector all_blocks_; // All basic blocks in the schedule. 321 BasicBlockVector all_blocks_; // All basic blocks in the schedule.
316 BasicBlockVector nodeid_to_block_; // Map from node to containing block. 322 BasicBlockVector nodeid_to_block_; // Map from node to containing block.
317 BasicBlockVector rpo_order_; // Reverse-post-order block list. 323 BasicBlockVector rpo_order_; // Reverse-post-order block list.
318 BasicBlockVector immediate_dominator_; // Maps to a block's immediate
319 // dominator, indexed by block
320 // id.
321 }; 324 };
322 325
323 OStream& operator<<(OStream& os, const Schedule& s); 326 OStream& operator<<(OStream& os, const Schedule& s);
324 } 327 }
325 } 328 }
326 } // namespace v8::internal::compiler 329 } // namespace v8::internal::compiler
327 330
328 #endif // V8_COMPILER_SCHEDULE_H_ 331 #endif // V8_COMPILER_SCHEDULE_H_
OLDNEW
« no previous file with comments | « src/compiler/pipeline.cc ('k') | src/compiler/scheduler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698