V8 Project
schedule.h
Go to the documentation of this file.
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
3 // found in the LICENSE file.
4 
5 #ifndef V8_COMPILER_SCHEDULE_H_
6 #define V8_COMPILER_SCHEDULE_H_
7 
8 #include <vector>
9 
10 #include "src/v8.h"
11 
16 #include "src/compiler/node.h"
17 #include "src/compiler/opcodes.h"
18 #include "src/zone.h"
19 
20 namespace v8 {
21 namespace internal {
22 namespace compiler {
23 
24 class BasicBlock;
25 class BasicBlockInstrumentor;
26 class Graph;
27 class ConstructScheduleData;
28 class CodeGenerator; // Because of a namespace bug in clang.
29 
31  public:
32  // Possible control nodes that can end a block.
33  enum Control {
34  kNone, // Control not initialized yet.
35  kGoto, // Goto a single successor block.
36  kBranch, // Branch if true to first successor, otherwise second.
37  kReturn, // Return a value from this method.
38  kThrow // Throw an exception.
39  };
40 
41  int32_t rpo_number_; // special RPO number of the block.
42  BasicBlock* dominator_; // Immediate dominator of the block.
43  BasicBlock* loop_header_; // Pointer to dominating loop header basic block,
44  // NULL if none. For loop headers, this points to
45  // enclosing loop header.
46  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 code_start_; // start index of arch-specific code.
49  int32_t code_end_; // end index of arch-specific code.
50  bool deferred_; // {true} if this block is considered the slow
51  // path.
52  Control control_; // Control at the end of the block.
53  Node* control_input_; // Input value for control.
54  NodeVector nodes_; // nodes of this block in forward order.
55 
56  explicit BasicBlockData(Zone* zone)
57  : rpo_number_(-1),
60  loop_depth_(0),
61  loop_end_(-1),
62  code_start_(-1),
63  code_end_(-1),
65  control_(kNone),
67  nodes_(zone) {}
68 
69  inline bool IsLoopHeader() const { return loop_end_ >= 0; }
70  inline bool LoopContains(BasicBlockData* block) const {
71  // RPO numbers must be initialized.
72  DCHECK(rpo_number_ >= 0);
73  DCHECK(block->rpo_number_ >= 0);
74  if (loop_end_ < 0) return false; // This is not a loop.
75  return block->rpo_number_ >= rpo_number_ && block->rpo_number_ < loop_end_;
76  }
78  DCHECK(code_start_ >= 0);
79  DCHECK(code_end_ > 0);
81  return code_start_;
82  }
84  DCHECK(code_start_ >= 0);
85  DCHECK(code_end_ > 0);
87  return code_end_ - 1;
88  }
89 };
90 
92 
93 // A basic block contains an ordered list of nodes and ends with a control
94 // node. Note that if a basic block has phis, then all phis must appear as the
95 // first nodes in the block.
96 class BasicBlock FINAL : public GenericNode<BasicBlockData, BasicBlock> {
97  public:
98  BasicBlock(GenericGraphBase* graph, int input_count)
99  : GenericNode<BasicBlockData, BasicBlock>(graph, input_count) {}
100 
101  typedef Uses Successors;
102  typedef Inputs Predecessors;
103 
104  Successors successors() { return static_cast<Successors>(uses()); }
105  Predecessors predecessors() { return static_cast<Predecessors>(inputs()); }
106 
107  int PredecessorCount() { return InputCount(); }
108  BasicBlock* PredecessorAt(int index) { return InputAt(index); }
109 
110  int SuccessorCount() { return UseCount(); }
111  BasicBlock* SuccessorAt(int index) { return UseAt(index); }
112 
113  int PredecessorIndexOf(BasicBlock* predecessor) {
114  BasicBlock::Predecessors predecessors = this->predecessors();
115  for (BasicBlock::Predecessors::iterator i = predecessors.begin();
116  i != predecessors.end(); ++i) {
117  if (*i == predecessor) return i.index();
118  }
119  return -1;
120  }
121 
122  inline BasicBlock* loop_header() {
123  return static_cast<BasicBlock*>(loop_header_);
124  }
125  inline BasicBlock* ContainingLoop() {
126  if (IsLoopHeader()) return this;
127  return static_cast<BasicBlock*>(loop_header_);
128  }
129 
130  typedef NodeVector::iterator iterator;
131  iterator begin() { return nodes_.begin(); }
132  iterator end() { return nodes_.end(); }
133 
134  typedef NodeVector::const_iterator const_iterator;
135  const_iterator begin() const { return nodes_.begin(); }
136  const_iterator end() const { return nodes_.end(); }
137 
138  typedef NodeVector::reverse_iterator reverse_iterator;
139  reverse_iterator rbegin() { return nodes_.rbegin(); }
140  reverse_iterator rend() { return nodes_.rend(); }
141 
142  private:
144 };
145 
148 
150 typedef BasicBlockVector::iterator BasicBlockVectorIter;
151 typedef BasicBlockVector::reverse_iterator BasicBlockVectorRIter;
152 
153 // A schedule represents the result of assigning nodes to basic blocks
154 // 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
156 // by the graph's dependencies. A schedule is required to generate code.
157 class Schedule : public GenericGraph<BasicBlock> {
158  public:
159  explicit Schedule(Zone* zone, size_t node_count_hint = 0)
160  : GenericGraph<BasicBlock>(zone),
161  zone_(zone),
162  all_blocks_(zone),
164  rpo_order_(zone) {
165  SetStart(NewBasicBlock()); // entry.
166  SetEnd(NewBasicBlock()); // exit.
167  nodeid_to_block_.reserve(node_count_hint);
168  }
169 
170  // Return the block which contains {node}, if any.
171  BasicBlock* block(Node* node) const {
172  if (node->id() < static_cast<NodeId>(nodeid_to_block_.size())) {
173  return nodeid_to_block_[node->id()];
174  }
175  return NULL;
176  }
177 
178  bool IsScheduled(Node* node) {
179  int length = static_cast<int>(nodeid_to_block_.size());
180  if (node->id() >= length) return false;
181  return nodeid_to_block_[node->id()] != NULL;
182  }
183 
184  BasicBlock* GetBlockById(int block_id) { return all_blocks_[block_id]; }
185 
186  int BasicBlockCount() const { return NodeCount(); }
187  int RpoBlockCount() const { return static_cast<int>(rpo_order_.size()); }
188 
190 
191  // Return a list of all the blocks in the schedule, in arbitrary order.
193 
194  // Check if nodes {a} and {b} are in the same block.
195  inline bool SameBasicBlock(Node* a, Node* b) const {
196  BasicBlock* block = this->block(a);
197  return block != NULL && block == this->block(b);
198  }
199 
200  // BasicBlock building: create a new block.
201  inline BasicBlock* NewBasicBlock() {
202  BasicBlock* block =
203  BasicBlock::New(this, 0, static_cast<BasicBlock**>(NULL));
204  all_blocks_.push_back(block);
205  return block;
206  }
207 
208  // BasicBlock building: records that a node will later be added to a block but
209  // doesn't actually add the node to the block.
210  inline void PlanNode(BasicBlock* block, Node* node) {
211  if (FLAG_trace_turbo_scheduler) {
212  PrintF("Planning #%d:%s for future add to B%d\n", node->id(),
213  node->op()->mnemonic(), block->id());
214  }
215  DCHECK(this->block(node) == NULL);
216  SetBlockForNode(block, node);
217  }
218 
219  // BasicBlock building: add a node to the end of the block.
220  inline void AddNode(BasicBlock* block, Node* node) {
221  if (FLAG_trace_turbo_scheduler) {
222  PrintF("Adding #%d:%s to B%d\n", node->id(), node->op()->mnemonic(),
223  block->id());
224  }
225  DCHECK(this->block(node) == NULL || this->block(node) == block);
226  block->nodes_.push_back(node);
227  SetBlockForNode(block, node);
228  }
229 
230  // BasicBlock building: add a goto to the end of {block}.
231  void AddGoto(BasicBlock* block, BasicBlock* succ) {
232  DCHECK(block->control_ == BasicBlock::kNone);
233  block->control_ = BasicBlock::kGoto;
234  AddSuccessor(block, succ);
235  }
236 
237  // BasicBlock building: add a branch at the end of {block}.
238  void AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
239  BasicBlock* fblock) {
240  DCHECK(block->control_ == BasicBlock::kNone);
241  DCHECK(branch->opcode() == IrOpcode::kBranch);
242  block->control_ = BasicBlock::kBranch;
243  AddSuccessor(block, tblock);
244  AddSuccessor(block, fblock);
245  SetControlInput(block, branch);
246  if (branch->opcode() == IrOpcode::kBranch) {
247  // TODO(titzer): require a Branch node here. (sloppy tests).
248  SetBlockForNode(block, branch);
249  }
250  }
251 
252  // BasicBlock building: add a return at the end of {block}.
253  void AddReturn(BasicBlock* block, Node* input) {
254  DCHECK(block->control_ == BasicBlock::kNone);
255  block->control_ = BasicBlock::kReturn;
256  SetControlInput(block, input);
257  if (block != end()) AddSuccessor(block, end());
258  if (input->opcode() == IrOpcode::kReturn) {
259  // TODO(titzer): require a Return node here. (sloppy tests).
260  SetBlockForNode(block, input);
261  }
262  }
263 
264  // BasicBlock building: add a throw at the end of {block}.
265  void AddThrow(BasicBlock* block, Node* input) {
266  DCHECK(block->control_ == BasicBlock::kNone);
267  block->control_ = BasicBlock::kThrow;
268  SetControlInput(block, input);
269  if (block != end()) AddSuccessor(block, end());
270  }
271 
272  friend class Scheduler;
273  friend class CodeGenerator;
274 
275  void AddSuccessor(BasicBlock* block, BasicBlock* succ) {
276  succ->AppendInput(zone_, block);
277  }
278 
280 
281  private:
282  friend class ScheduleVisualizer;
284 
285  void SetControlInput(BasicBlock* block, Node* node) {
286  block->control_input_ = node;
287  SetBlockForNode(block, node);
288  }
289 
290  void SetBlockForNode(BasicBlock* block, Node* node) {
291  int length = static_cast<int>(nodeid_to_block_.size());
292  if (node->id() >= length) {
293  nodeid_to_block_.resize(node->id() + 1);
294  }
295  nodeid_to_block_[node->id()] = block;
296  }
297 
299  BasicBlockVector all_blocks_; // All basic blocks in the schedule.
300  BasicBlockVector nodeid_to_block_; // Map from node to containing block.
301  BasicBlockVector rpo_order_; // Reverse-post-order block list.
302 };
303 
304 OStream& operator<<(OStream& os, const Schedule& s);
305 }
306 }
307 } // namespace v8::internal::compiler
308 
309 #endif // V8_COMPILER_SCHEDULE_H_
Source to read snapshot and builtins files from.
Definition: lithium-arm.h:372
bool LoopContains(BasicBlockData *block) const
Definition: schedule.h:70
const_iterator end() const
Definition: schedule.h:136
BasicBlock * ContainingLoop()
Definition: schedule.h:125
Predecessors predecessors()
Definition: schedule.h:105
reverse_iterator rbegin()
Definition: schedule.h:139
BasicBlock * PredecessorAt(int index)
Definition: schedule.h:108
int PredecessorIndexOf(BasicBlock *predecessor)
Definition: schedule.h:113
NodeVector::const_iterator const_iterator
Definition: schedule.h:134
InstructionDeque::const_iterator const_iterator
Definition: instruction.h:862
BasicBlock * SuccessorAt(int index)
Definition: schedule.h:111
reverse_iterator rend()
Definition: schedule.h:140
const_iterator begin() const
Definition: schedule.h:135
NodeVector::reverse_iterator reverse_iterator
Definition: schedule.h:138
BasicBlock(GenericGraphBase *graph, int input_count)
Definition: schedule.h:98
BasicBlock * loop_header()
Definition: schedule.h:122
NodeVector::iterator iterator
Definition: schedule.h:130
void SetBlockForNode(BasicBlock *block, Node *node)
Definition: schedule.h:290
ContainerPointerWrapper< BasicBlockVector > BasicBlocks
Definition: schedule.h:189
void AddThrow(BasicBlock *block, Node *input)
Definition: schedule.h:265
void PlanNode(BasicBlock *block, Node *node)
Definition: schedule.h:210
void AddGoto(BasicBlock *block, BasicBlock *succ)
Definition: schedule.h:231
void AddSuccessor(BasicBlock *block, BasicBlock *succ)
Definition: schedule.h:275
void AddReturn(BasicBlock *block, Node *input)
Definition: schedule.h:253
BasicBlockVector all_blocks_
Definition: schedule.h:299
BasicBlock * GetBlockById(int block_id)
Definition: schedule.h:184
bool SameBasicBlock(Node *a, Node *b) const
Definition: schedule.h:195
void AddBranch(BasicBlock *block, Node *branch, BasicBlock *tblock, BasicBlock *fblock)
Definition: schedule.h:238
BasicBlockVector nodeid_to_block_
Definition: schedule.h:300
void SetControlInput(BasicBlock *block, Node *node)
Definition: schedule.h:285
void AddNode(BasicBlock *block, Node *node)
Definition: schedule.h:220
bool IsScheduled(Node *node)
Definition: schedule.h:178
BasicBlock * block(Node *node) const
Definition: schedule.h:171
BasicBlockVector * rpo_order()
Definition: schedule.h:279
Schedule(Zone *zone, size_t node_count_hint=0)
Definition: schedule.h:159
BasicBlockVector rpo_order_
Definition: schedule.h:301
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
int int32_t
Definition: unicode.cc:24
ZoneVector< BasicBlock * > BasicBlockVector
Definition: schedule.h:149
std::ostream & operator<<(std::ostream &os, const MachineType &type)
BasicBlockVector::iterator BasicBlockVectorIter
Definition: schedule.h:150
BasicBlockVector::reverse_iterator BasicBlockVectorRIter
Definition: schedule.h:151
GenericGraphVisit::NullNodeVisitor< BasicBlockData, BasicBlock > NullBasicBlockVisitor
Definition: schedule.h:147
void PrintF(const char *format,...)
Definition: utils.cc:80
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20