V8 Project
v8::internal::HBoundsCheckEliminationPhase Class Reference

#include <hydrogen-bce.h>

+ Inheritance diagram for v8::internal::HBoundsCheckEliminationPhase:
+ Collaboration diagram for v8::internal::HBoundsCheckEliminationPhase:

Public Member Functions

 HBoundsCheckEliminationPhase (HGraph *graph)
 
void Run ()
 
- Public Member Functions inherited from v8::internal::HPhase
 HPhase (const char *name, HGraph *graph)
 
 ~HPhase ()
 

Private Member Functions

void EliminateRedundantBoundsChecks (HBasicBlock *bb)
 
BoundsCheckBbDataPreProcessBlock (HBasicBlock *bb)
 
void PostProcessBlock (HBasicBlock *bb, BoundsCheckBbData *data)
 
 DISALLOW_COPY_AND_ASSIGN (HBoundsCheckEliminationPhase)
 

Private Attributes

BoundsCheckTable table_
 

Additional Inherited Members

- Protected Member Functions inherited from v8::internal::HPhase
HGraph * graph () const
 

Detailed Description

Definition at line 29 of file hydrogen-bce.h.

Constructor & Destructor Documentation

◆ HBoundsCheckEliminationPhase()

v8::internal::HBoundsCheckEliminationPhase::HBoundsCheckEliminationPhase ( HGraph *  graph)
inlineexplicit

Definition at line 31 of file hydrogen-bce.h.

32  : HPhase("H_Bounds checks elimination", graph), table_(zone()) { }
HGraph * graph() const
Definition: hydrogen.h:2802
HPhase(const char *name, HGraph *graph)
Definition: hydrogen.h:2796

Member Function Documentation

◆ DISALLOW_COPY_AND_ASSIGN()

v8::internal::HBoundsCheckEliminationPhase::DISALLOW_COPY_AND_ASSIGN ( HBoundsCheckEliminationPhase  )
private

◆ EliminateRedundantBoundsChecks()

void v8::internal::HBoundsCheckEliminationPhase::EliminateRedundantBoundsChecks ( HBasicBlock *  bb)
private

Definition at line 339 of file hydrogen-bce.cc.

340  {
341  // Allocate the stack.
342  HBoundsCheckEliminationState* stack =
343  zone()->NewArray<HBoundsCheckEliminationState>(graph()->blocks()->length());
344 
345  // Explicitly push the entry block.
346  stack[0].block_ = entry;
347  stack[0].bb_data_list_ = PreProcessBlock(entry);
348  stack[0].index_ = 0;
349  int stack_depth = 1;
350 
351  // Implement depth-first traversal with a stack.
352  while (stack_depth > 0) {
353  int current = stack_depth - 1;
354  HBoundsCheckEliminationState* state = &stack[current];
355  const ZoneList<HBasicBlock*>* children = state->block_->dominated_blocks();
356 
357  if (state->index_ < children->length()) {
358  // Recursively visit children blocks.
359  HBasicBlock* child = children->at(state->index_++);
360  int next = stack_depth++;
361  stack[next].block_ = child;
362  stack[next].bb_data_list_ = PreProcessBlock(child);
363  stack[next].index_ = 0;
364  } else {
365  // Finished with all children; post process the block.
366  PostProcessBlock(state->block_, state->bb_data_list_);
367  stack_depth--;
368  }
369  }
370 }
void PostProcessBlock(HBasicBlock *bb, BoundsCheckBbData *data)
BoundsCheckBbData * PreProcessBlock(HBasicBlock *bb)

References v8::internal::List< T, AllocationPolicy >::at(), v8::internal::HBoundsCheckEliminationState::bb_data_list_, v8::internal::HBoundsCheckEliminationState::block_, v8::internal::HPhase::graph(), v8::internal::HBoundsCheckEliminationState::index_, PostProcessBlock(), and PreProcessBlock().

Referenced by Run().

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

◆ PostProcessBlock()

void v8::internal::HBoundsCheckEliminationPhase::PostProcessBlock ( HBasicBlock *  bb,
BoundsCheckBbData data 
)
private

Definition at line 453 of file hydrogen-bce.cc.

454  {
455  while (data != NULL) {
456  if (data->FatherInDominatorTree()) {
457  table_.Insert(data->Key(), data->FatherInDominatorTree(), zone());
458  } else {
459  table_.Delete(data->Key());
460  }
461  data = data->NextInBasicBlock();
462  }
463 }
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

References v8::internal::BoundsCheckBbData::FatherInDominatorTree(), v8::internal::BoundsCheckBbData::Key(), v8::internal::BoundsCheckBbData::NextInBasicBlock(), NULL, and table_.

Referenced by EliminateRedundantBoundsChecks().

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

◆ PreProcessBlock()

BoundsCheckBbData * v8::internal::HBoundsCheckEliminationPhase::PreProcessBlock ( HBasicBlock *  bb)
private

Definition at line 373 of file hydrogen-bce.cc.

374  {
375  BoundsCheckBbData* bb_data_list = NULL;
376 
377  for (HInstructionIterator it(bb); !it.Done(); it.Advance()) {
378  HInstruction* i = it.Current();
379  if (!i->IsBoundsCheck()) continue;
380 
381  HBoundsCheck* check = HBoundsCheck::cast(i);
382  int32_t offset;
383  BoundsCheckKey* key =
384  BoundsCheckKey::Create(zone(), check, &offset);
385  if (key == NULL) continue;
386  BoundsCheckBbData** data_p = table_.LookupOrInsert(key, zone());
387  BoundsCheckBbData* data = *data_p;
388  if (data == NULL) {
389  bb_data_list = new(zone()) BoundsCheckBbData(key,
390  offset,
391  offset,
392  bb,
393  check,
394  check,
395  bb_data_list,
396  NULL);
397  *data_p = bb_data_list;
398  if (FLAG_trace_bce) {
399  base::OS::Print("Fresh bounds check data for block #%d: [%d]\n",
400  bb->block_id(), offset);
401  }
402  } else if (data->OffsetIsCovered(offset)) {
403  bb->graph()->isolate()->counters()->
404  bounds_checks_eliminated()->Increment();
405  if (FLAG_trace_bce) {
406  base::OS::Print("Eliminating bounds check #%d, offset %d is covered\n",
407  check->id(), offset);
408  }
409  check->DeleteAndReplaceWith(check->ActualValue());
410  } else if (data->BasicBlock() == bb) {
411  // TODO(jkummerow): I think the following logic would be preferable:
412  // if (data->Basicblock() == bb ||
413  // graph()->use_optimistic_licm() ||
414  // bb->IsLoopSuccessorDominator()) {
415  // data->CoverCheck(check, offset)
416  // } else {
417  // /* add pristine BCBbData like in (data == NULL) case above */
418  // }
419  // Even better would be: distinguish between read-only dominator-imposed
420  // knowledge and modifiable upper/lower checks.
421  // What happens currently is that the first bounds check in a dominated
422  // block will stay around while any further checks are hoisted out,
423  // which doesn't make sense. Investigate/fix this in a future CL.
424  data->CoverCheck(check, offset);
425  } else if (graph()->use_optimistic_licm() ||
426  bb->IsLoopSuccessorDominator()) {
427  int32_t new_lower_offset = offset < data->LowerOffset()
428  ? offset
429  : data->LowerOffset();
430  int32_t new_upper_offset = offset > data->UpperOffset()
431  ? offset
432  : data->UpperOffset();
433  bb_data_list = new(zone()) BoundsCheckBbData(key,
434  new_lower_offset,
435  new_upper_offset,
436  bb,
437  data->LowerCheck(),
438  data->UpperCheck(),
439  bb_data_list,
440  data);
441  if (FLAG_trace_bce) {
442  base::OS::Print("Updated bounds check data for block #%d: [%d - %d]\n",
443  bb->block_id(), new_lower_offset, new_upper_offset);
444  }
445  table_.Insert(key, bb_data_list, zone());
446  }
447  }
448 
449  return bb_data_list;
450 }
static void Print(const char *format,...)
static BoundsCheckKey * Create(Zone *zone, HBoundsCheck *check, int32_t *offset)
Definition: hydrogen-bce.cc:29
int int32_t
Definition: unicode.cc:24

References v8::internal::BoundsCheckBbData::BasicBlock(), v8::internal::BoundsCheckBbData::CoverCheck(), v8::internal::BoundsCheckKey::Create(), v8::internal::HPhase::graph(), v8::internal::BoundsCheckBbData::LowerCheck(), v8::internal::BoundsCheckBbData::LowerOffset(), NULL, v8::internal::BoundsCheckBbData::OffsetIsCovered(), v8::base::OS::Print(), table_, v8::internal::BoundsCheckBbData::UpperCheck(), and v8::internal::BoundsCheckBbData::UpperOffset().

Referenced by EliminateRedundantBoundsChecks().

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

◆ Run()

void v8::internal::HBoundsCheckEliminationPhase::Run ( )
inline

Definition at line 34 of file hydrogen-bce.h.

34  {
35  EliminateRedundantBoundsChecks(graph()->entry_block());
36  }
void EliminateRedundantBoundsChecks(HBasicBlock *bb)

References EliminateRedundantBoundsChecks(), and v8::internal::HPhase::graph().

+ Here is the call graph for this function:

Member Data Documentation

◆ table_

BoundsCheckTable v8::internal::HBoundsCheckEliminationPhase::table_
private

Definition at line 43 of file hydrogen-bce.h.

Referenced by PostProcessBlock(), and PreProcessBlock().


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