V8 Project
v8::internal::compiler::ScheduleVerifier Class Reference

#include <verifier.h>

+ Collaboration diagram for v8::internal::compiler::ScheduleVerifier:

Static Public Member Functions

static void Run (Schedule *schedule)
 

Detailed Description

Definition at line 29 of file verifier.h.

Member Function Documentation

◆ Run()

void v8::internal::compiler::ScheduleVerifier::Run ( Schedule schedule)
static

Definition at line 295 of file verifier.cc.

295  {
296  const int count = schedule->BasicBlockCount();
297  Zone tmp_zone(schedule->zone()->isolate());
298  Zone* zone = &tmp_zone;
299  BasicBlock* start = schedule->start();
300  BasicBlockVector* rpo_order = schedule->rpo_order();
301 
302  // Verify the RPO order contains only blocks from this schedule.
303  CHECK_GE(count, static_cast<int>(rpo_order->size()));
304  for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
305  ++b) {
306  CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
307  }
308 
309  // Verify RPO numbers of blocks.
310  CHECK_EQ(start, rpo_order->at(0)); // Start should be first.
311  for (size_t b = 0; b < rpo_order->size(); b++) {
312  BasicBlock* block = rpo_order->at(b);
313  CHECK_EQ(static_cast<int>(b), block->rpo_number_);
314  BasicBlock* dom = block->dominator_;
315  if (b == 0) {
316  // All blocks except start should have a dominator.
317  CHECK_EQ(NULL, dom);
318  } else {
319  // Check that the immediate dominator appears somewhere before the block.
320  CHECK_NE(NULL, dom);
321  CHECK_LT(dom->rpo_number_, block->rpo_number_);
322  }
323  }
324 
325  // Verify that all blocks reachable from start are in the RPO.
326  BoolVector marked(count, false, zone);
327  {
328  ZoneQueue<BasicBlock*> queue(zone);
329  queue.push(start);
330  marked[start->id()] = true;
331  while (!queue.empty()) {
332  BasicBlock* block = queue.front();
333  queue.pop();
334  for (int s = 0; s < block->SuccessorCount(); s++) {
335  BasicBlock* succ = block->SuccessorAt(s);
336  if (!marked[succ->id()]) {
337  marked[succ->id()] = true;
338  queue.push(succ);
339  }
340  }
341  }
342  }
343  // Verify marked blocks are in the RPO.
344  for (int i = 0; i < count; i++) {
345  BasicBlock* block = schedule->GetBlockById(i);
346  if (marked[i]) {
347  CHECK_GE(block->rpo_number_, 0);
348  CHECK_EQ(block, rpo_order->at(block->rpo_number_));
349  }
350  }
351  // Verify RPO blocks are marked.
352  for (size_t b = 0; b < rpo_order->size(); b++) {
353  CHECK(marked[rpo_order->at(b)->id()]);
354  }
355 
356  {
357  // Verify the dominance relation.
358  ZoneList<BitVector*> dominators(count, zone);
359  dominators.Initialize(count, zone);
360  dominators.AddBlock(NULL, count, zone);
361 
362  // Compute a set of all the nodes that dominate a given node by using
363  // a forward fixpoint. O(n^2).
364  ZoneQueue<BasicBlock*> queue(zone);
365  queue.push(start);
366  dominators[start->id()] = new (zone) BitVector(count, zone);
367  while (!queue.empty()) {
368  BasicBlock* block = queue.front();
369  queue.pop();
370  BitVector* block_doms = dominators[block->id()];
371  BasicBlock* idom = block->dominator_;
372  if (idom != NULL && !block_doms->Contains(idom->id())) {
373  V8_Fatal(__FILE__, __LINE__, "Block B%d is not dominated by B%d",
374  block->id(), idom->id());
375  }
376  for (int s = 0; s < block->SuccessorCount(); s++) {
377  BasicBlock* succ = block->SuccessorAt(s);
378  BitVector* succ_doms = dominators[succ->id()];
379 
380  if (succ_doms == NULL) {
381  // First time visiting the node. S.doms = B U B.doms
382  succ_doms = new (zone) BitVector(count, zone);
383  succ_doms->CopyFrom(*block_doms);
384  succ_doms->Add(block->id());
385  dominators[succ->id()] = succ_doms;
386  queue.push(succ);
387  } else {
388  // Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms)
389  bool had = succ_doms->Contains(block->id());
390  if (had) succ_doms->Remove(block->id());
391  if (succ_doms->IntersectIsChanged(*block_doms)) queue.push(succ);
392  if (had) succ_doms->Add(block->id());
393  }
394  }
395  }
396 
397  // Verify the immediateness of dominators.
398  for (BasicBlockVector::iterator b = rpo_order->begin();
399  b != rpo_order->end(); ++b) {
400  BasicBlock* block = *b;
401  BasicBlock* idom = block->dominator_;
402  if (idom == NULL) continue;
403  BitVector* block_doms = dominators[block->id()];
404 
405  for (BitVector::Iterator it(block_doms); !it.Done(); it.Advance()) {
406  BasicBlock* dom = schedule->GetBlockById(it.Current());
407  if (dom != idom && !dominators[idom->id()]->Contains(dom->id())) {
408  V8_Fatal(__FILE__, __LINE__,
409  "Block B%d is not immediately dominated by B%d", block->id(),
410  idom->id());
411  }
412  }
413  }
414  }
415 
416  // Verify phis are placed in the block of their control input.
417  for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
418  ++b) {
419  for (BasicBlock::const_iterator i = (*b)->begin(); i != (*b)->end(); ++i) {
420  Node* phi = *i;
421  if (phi->opcode() != IrOpcode::kPhi) continue;
422  // TODO(titzer): Nasty special case. Phis from RawMachineAssembler
423  // schedules don't have control inputs.
424  if (phi->InputCount() >
426  Node* control = NodeProperties::GetControlInput(phi);
427  CHECK(control->opcode() == IrOpcode::kMerge ||
428  control->opcode() == IrOpcode::kLoop);
429  CHECK_EQ((*b), schedule->block(control));
430  }
431  }
432  }
433 
434  // Verify that all uses are dominated by their definitions.
435  for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
436  ++b) {
437  BasicBlock* block = *b;
438 
439  // Check inputs to control for this block.
440  Node* control = block->control_input_;
441  if (control != NULL) {
442  CHECK_EQ(block, schedule->block(control));
443  CheckInputsDominate(schedule, block, control,
444  static_cast<int>(block->nodes_.size()) - 1);
445  }
446  // Check inputs for all nodes in the block.
447  for (size_t i = 0; i < block->nodes_.size(); i++) {
448  Node* node = block->nodes_[i];
449  CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
450  }
451  }
452 }
static Node * GetControlInput(Node *node, int index=0)
static int GetValueInputCount(const Operator *op)
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
void V8_Fatal(const char *file, int line, const char *format,...)
Definition: logging.cc:75
#define CHECK_EQ(expected, value)
Definition: logging.h:169
#define CHECK_LT(a, b)
Definition: logging.h:179
#define CHECK(condition)
Definition: logging.h:36
#define CHECK_NE(unexpected, value)
Definition: logging.h:173
#define CHECK_GE(a, b)
Definition: logging.h:178
ZoneVector< BasicBlock * > BasicBlockVector
Definition: schedule.h:149
static void CheckInputsDominate(Schedule *schedule, BasicBlock *block, Node *node, int use_pos)
Definition: verifier.cc:274
ZoneVector< bool > BoolVector

References v8::internal::BitVector::Add(), v8::internal::List< T, AllocationPolicy >::AddBlock(), v8::internal::compiler::Schedule::BasicBlockCount(), v8::internal::compiler::Schedule::block(), CHECK, CHECK_EQ, CHECK_GE, CHECK_LT, CHECK_NE, v8::internal::compiler::CheckInputsDominate(), v8::internal::List< T, AllocationPolicy >::Contains(), v8::internal::BitVector::Contains(), v8::internal::BitVector::CopyFrom(), v8::internal::compiler::Schedule::GetBlockById(), v8::internal::compiler::NodeProperties::GetControlInput(), v8::internal::compiler::OperatorProperties::GetValueInputCount(), v8::internal::BitVector::IntersectIsChanged(), v8::internal::Zone::isolate(), NULL, v8::internal::BitVector::Remove(), v8::internal::compiler::Schedule::rpo_order(), v8::internal::compiler::GenericGraph< V >::start(), V8_Fatal(), and v8::internal::compiler::GenericGraphBase::zone().

Referenced by v8::internal::compiler::Pipeline::ComputeSchedule().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

The documentation for this class was generated from the following files: