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

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
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_(NodeVector::allocator_type(zone)) {} 68 nodes_(NodeVector::allocator_type(zone)) {}
67 69
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 // and ordering them within basic blocks. Prior to computing a schedule, 156 // and ordering them within basic blocks. Prior to computing a schedule,
155 // a graph has no notion of control flow ordering other than that induced 157 // a graph has no notion of control flow ordering other than that induced
156 // by the graph's dependencies. A schedule is required to generate code. 158 // by the graph's dependencies. A schedule is required to generate code.
157 class Schedule : public GenericGraph<BasicBlock> { 159 class Schedule : public GenericGraph<BasicBlock> {
158 public: 160 public:
159 explicit Schedule(Zone* zone) 161 explicit Schedule(Zone* zone)
160 : GenericGraph<BasicBlock>(zone), 162 : GenericGraph<BasicBlock>(zone),
161 zone_(zone), 163 zone_(zone),
162 all_blocks_(BasicBlockVector::allocator_type(zone)), 164 all_blocks_(BasicBlockVector::allocator_type(zone)),
163 nodeid_to_block_(BasicBlockVector::allocator_type(zone)), 165 nodeid_to_block_(BasicBlockVector::allocator_type(zone)),
164 rpo_order_(BasicBlockVector::allocator_type(zone)), 166 rpo_order_(BasicBlockVector::allocator_type(zone)) {
165 immediate_dominator_(BasicBlockVector::allocator_type(zone)) {
166 SetStart(NewBasicBlock()); // entry. 167 SetStart(NewBasicBlock()); // entry.
167 SetEnd(NewBasicBlock()); // exit. 168 SetEnd(NewBasicBlock()); // exit.
168 } 169 }
169 170
170 // Return the block which contains {node}, if any. 171 // Return the block which contains {node}, if any.
171 BasicBlock* block(Node* node) const { 172 BasicBlock* block(Node* node) const {
172 if (node->id() < static_cast<NodeId>(nodeid_to_block_.size())) { 173 if (node->id() < static_cast<NodeId>(nodeid_to_block_.size())) {
173 return nodeid_to_block_[node->id()]; 174 return nodeid_to_block_[node->id()];
174 } 175 }
175 return NULL; 176 return NULL;
176 } 177 }
177 178
178 BasicBlock* dominator(BasicBlock* block) {
179 return immediate_dominator_[block->id()];
180 }
181
182 bool IsScheduled(Node* node) { 179 bool IsScheduled(Node* node) {
183 int length = static_cast<int>(nodeid_to_block_.size()); 180 int length = static_cast<int>(nodeid_to_block_.size());
184 if (node->id() >= length) return false; 181 if (node->id() >= length) return false;
185 return nodeid_to_block_[node->id()] != NULL; 182 return nodeid_to_block_[node->id()] != NULL;
186 } 183 }
187 184
188 BasicBlock* GetBlockById(int block_id) { return all_blocks_[block_id]; } 185 BasicBlock* GetBlockById(int block_id) { return all_blocks_[block_id]; }
189 186
190 int BasicBlockCount() const { return NodeCount(); } 187 int BasicBlockCount() const { return NodeCount(); }
191 int RpoBlockCount() const { return static_cast<int>(rpo_order_.size()); } 188 int RpoBlockCount() const { return static_cast<int>(rpo_order_.size()); }
(...skipping 14 matching lines...) Expand all
206 BasicBlock* block = 203 BasicBlock* block =
207 BasicBlock::New(this, 0, static_cast<BasicBlock**>(NULL)); 204 BasicBlock::New(this, 0, static_cast<BasicBlock**>(NULL));
208 all_blocks_.push_back(block); 205 all_blocks_.push_back(block);
209 return block; 206 return block;
210 } 207 }
211 208
212 // BasicBlock building: records that a node will later be added to a block but 209 // BasicBlock building: records that a node will later be added to a block but
213 // doesn't actually add the node to the block. 210 // doesn't actually add the node to the block.
214 inline void PlanNode(BasicBlock* block, Node* node) { 211 inline void PlanNode(BasicBlock* block, Node* node) {
215 if (FLAG_trace_turbo_scheduler) { 212 if (FLAG_trace_turbo_scheduler) {
216 PrintF("Planning node %d for future add to block %d\n", node->id(), 213 PrintF("Planning #%d:%s for future add to B%d\n", node->id(),
217 block->id()); 214 node->op()->mnemonic(), block->id());
218 } 215 }
219 DCHECK(this->block(node) == NULL); 216 DCHECK(this->block(node) == NULL);
220 SetBlockForNode(block, node); 217 SetBlockForNode(block, node);
221 } 218 }
222 219
223 // BasicBlock building: add a node to the end of the block. 220 // BasicBlock building: add a node to the end of the block.
224 inline void AddNode(BasicBlock* block, Node* node) { 221 inline void AddNode(BasicBlock* block, Node* node) {
225 if (FLAG_trace_turbo_scheduler) { 222 if (FLAG_trace_turbo_scheduler) {
226 PrintF("Adding node %d to block %d\n", node->id(), block->id()); 223 PrintF("Adding #%d:%s to B%d\n", node->id(), node->op()->mnemonic(),
224 block->id());
227 } 225 }
228 DCHECK(this->block(node) == NULL || this->block(node) == block); 226 DCHECK(this->block(node) == NULL || this->block(node) == block);
229 block->nodes_.push_back(node); 227 block->nodes_.push_back(node);
230 SetBlockForNode(block, node); 228 SetBlockForNode(block, node);
231 } 229 }
232 230
233 // BasicBlock building: add a goto to the end of {block}. 231 // BasicBlock building: add a goto to the end of {block}.
234 void AddGoto(BasicBlock* block, BasicBlock* succ) { 232 void AddGoto(BasicBlock* block, BasicBlock* succ) {
235 DCHECK(block->control_ == BasicBlock::kNone); 233 DCHECK(block->control_ == BasicBlock::kNone);
236 block->control_ = BasicBlock::kGoto; 234 block->control_ = BasicBlock::kGoto;
237 AddSuccessor(block, succ); 235 AddSuccessor(block, succ);
238 } 236 }
239 237
240 // BasicBlock building: add a (branching) call at the end of {block}. 238 // BasicBlock building: add a (branching) call at the end of {block}.
241 void AddCall(BasicBlock* block, Node* call, BasicBlock* cont_block, 239 void AddCall(BasicBlock* block, Node* call, BasicBlock* cont_block,
242 BasicBlock* deopt_block) { 240 BasicBlock* deopt_block) {
243 DCHECK(block->control_ == BasicBlock::kNone); 241 DCHECK(block->control_ == BasicBlock::kNone);
244 DCHECK(call->opcode() == IrOpcode::kCall); 242 DCHECK(call->opcode() == IrOpcode::kCall);
245 block->control_ = BasicBlock::kCall; 243 block->control_ = BasicBlock::kCall;
246 // Insert the deopt block first so that the RPO order builder picks 244 // Insert the deopt block first so that the RPO order builder picks
247 // it first (and thus it ends up late in the RPO order). 245 // it first (and thus it ends up late in the RPO order).
248 AddSuccessor(block, deopt_block); 246 AddSuccessor(block, deopt_block);
249 AddSuccessor(block, cont_block); 247 AddSuccessor(block, cont_block);
250 SetControlInput(block, call); 248 SetControlInput(block, call);
249 SetBlockForNode(block, call);
251 } 250 }
252 251
253 // BasicBlock building: add a branch at the end of {block}. 252 // BasicBlock building: add a branch at the end of {block}.
254 void AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock, 253 void AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
255 BasicBlock* fblock) { 254 BasicBlock* fblock) {
256 DCHECK(block->control_ == BasicBlock::kNone); 255 DCHECK(block->control_ == BasicBlock::kNone);
257 DCHECK(branch->opcode() == IrOpcode::kBranch); 256 DCHECK(branch->opcode() == IrOpcode::kBranch);
258 block->control_ = BasicBlock::kBranch; 257 block->control_ = BasicBlock::kBranch;
259 AddSuccessor(block, tblock); 258 AddSuccessor(block, tblock);
260 AddSuccessor(block, fblock); 259 AddSuccessor(block, fblock);
261 SetControlInput(block, branch); 260 SetControlInput(block, branch);
261 if (branch->opcode() == IrOpcode::kBranch) {
262 // TODO(titzer): require a Branch node here. (sloppy tests).
263 SetBlockForNode(block, branch);
264 }
262 } 265 }
263 266
264 // BasicBlock building: add a return at the end of {block}. 267 // BasicBlock building: add a return at the end of {block}.
265 void AddReturn(BasicBlock* block, Node* input) { 268 void AddReturn(BasicBlock* block, Node* input) {
266 // TODO(titzer): require a Return node here.
267 DCHECK(block->control_ == BasicBlock::kNone); 269 DCHECK(block->control_ == BasicBlock::kNone);
268 block->control_ = BasicBlock::kReturn; 270 block->control_ = BasicBlock::kReturn;
269 SetControlInput(block, input); 271 SetControlInput(block, input);
270 if (block != end()) AddSuccessor(block, end()); 272 if (block != end()) AddSuccessor(block, end());
273 if (input->opcode() == IrOpcode::kReturn) {
274 // TODO(titzer): require a Return node here. (sloppy tests).
275 SetBlockForNode(block, input);
276 }
271 } 277 }
272 278
273 // BasicBlock building: add a throw at the end of {block}. 279 // BasicBlock building: add a throw at the end of {block}.
274 void AddThrow(BasicBlock* block, Node* input) { 280 void AddThrow(BasicBlock* block, Node* input) {
275 DCHECK(block->control_ == BasicBlock::kNone); 281 DCHECK(block->control_ == BasicBlock::kNone);
276 block->control_ = BasicBlock::kThrow; 282 block->control_ = BasicBlock::kThrow;
277 SetControlInput(block, input); 283 SetControlInput(block, input);
278 if (block != end()) AddSuccessor(block, end()); 284 if (block != end()) AddSuccessor(block, end());
279 } 285 }
280 286
(...skipping 28 matching lines...) Expand all
309 if (node->id() >= length) { 315 if (node->id() >= length) {
310 nodeid_to_block_.resize(node->id() + 1); 316 nodeid_to_block_.resize(node->id() + 1);
311 } 317 }
312 nodeid_to_block_[node->id()] = block; 318 nodeid_to_block_[node->id()] = block;
313 } 319 }
314 320
315 Zone* zone_; 321 Zone* zone_;
316 BasicBlockVector all_blocks_; // All basic blocks in the schedule. 322 BasicBlockVector all_blocks_; // All basic blocks in the schedule.
317 BasicBlockVector nodeid_to_block_; // Map from node to containing block. 323 BasicBlockVector nodeid_to_block_; // Map from node to containing block.
318 BasicBlockVector rpo_order_; // Reverse-post-order block list. 324 BasicBlockVector rpo_order_; // Reverse-post-order block list.
319 BasicBlockVector immediate_dominator_; // Maps to a block's immediate
320 // dominator, indexed by block
321 // id.
322 }; 325 };
323 326
324 OStream& operator<<(OStream& os, const Schedule& s); 327 OStream& operator<<(OStream& os, const Schedule& s);
325 } 328 }
326 } 329 }
327 } // namespace v8::internal::compiler 330 } // namespace v8::internal::compiler
328 331
329 #endif // V8_COMPILER_SCHEDULE_H_ 332 #endif // V8_COMPILER_SCHEDULE_H_
OLDNEW
« no previous file with comments | « src/compiler/pipeline.cc ('k') | src/compiler/scheduler.h » ('j') | src/compiler/scheduler.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698