V8 Project
v8::internal::HEnvironmentLivenessAnalysisPhase Class Reference

#include <hydrogen-environment-liveness.h>

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

Public Member Functions

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

Private Member Functions

void ZapEnvironmentSlot (int index, HSimulate *simulate)
 
void ZapEnvironmentSlotsInSuccessors (HBasicBlock *block, BitVector *live)
 
void ZapEnvironmentSlotsForInstruction (HEnvironmentMarker *marker)
 
void UpdateLivenessAtBlockEnd (HBasicBlock *block, BitVector *live)
 
void UpdateLivenessAtInstruction (HInstruction *instr, BitVector *live)
 
 DISALLOW_COPY_AND_ASSIGN (HEnvironmentLivenessAnalysisPhase)
 

Private Attributes

int block_count_
 
int maximum_environment_size_
 
ZoneList< BitVector * > live_at_block_start_
 
ZoneList< HSimulate * > first_simulate_
 
ZoneList< BitVector * > first_simulate_invalid_for_index_
 
ZoneList< HEnvironmentMarker * > markers_
 
bool collect_markers_
 
HSimulate * last_simulate_
 
BitVector went_live_since_last_simulate_
 

Additional Inherited Members

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

Detailed Description

Definition at line 23 of file hydrogen-environment-liveness.h.

Constructor & Destructor Documentation

◆ HEnvironmentLivenessAnalysisPhase()

v8::internal::HEnvironmentLivenessAnalysisPhase::HEnvironmentLivenessAnalysisPhase ( HGraph *  graph)
explicit

Definition at line 13 of file hydrogen-environment-liveness.cc.

15  : HPhase("H_Environment liveness analysis", graph),
16  block_count_(graph->blocks()->length()),
17  maximum_environment_size_(graph->maximum_environment_size()),
22  collect_markers_(true),
26  for (int i = 0; i < block_count_; ++i) {
28  new(zone()) BitVector(maximum_environment_size_, zone()), zone());
29  first_simulate_.Add(NULL, zone());
31  new(zone()) BitVector(maximum_environment_size_, zone()), zone());
32  }
33 }
HGraph * graph() const
Definition: hydrogen.h:2802
HPhase(const char *name, HGraph *graph)
Definition: hydrogen.h:2796
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:17
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

References v8::internal::List< T, AllocationPolicy >::Add(), block_count_, DCHECK, first_simulate_, first_simulate_invalid_for_index_, live_at_block_start_, maximum_environment_size_, and NULL.

+ Here is the call graph for this function:

Member Function Documentation

◆ DISALLOW_COPY_AND_ASSIGN()

v8::internal::HEnvironmentLivenessAnalysisPhase::DISALLOW_COPY_AND_ASSIGN ( HEnvironmentLivenessAnalysisPhase  )
private

◆ Run()

void v8::internal::HEnvironmentLivenessAnalysisPhase::Run ( )

Definition at line 158 of file hydrogen-environment-liveness.cc.

158  {
160 
161  // Main iteration. Compute liveness of environment slots, and store it
162  // for each block until it doesn't change any more. For efficiency, visit
163  // blocks in reverse order and walk backwards through each block. We
164  // need several iterations to propagate liveness through nested loops.
165  BitVector live(maximum_environment_size_, zone());
166  BitVector worklist(block_count_, zone());
167  for (int i = 0; i < block_count_; ++i) {
168  worklist.Add(i);
169  }
170  while (!worklist.IsEmpty()) {
171  for (int block_id = block_count_ - 1; block_id >= 0; --block_id) {
172  if (!worklist.Contains(block_id)) {
173  continue;
174  }
175  worklist.Remove(block_id);
177 
178  HBasicBlock* block = graph()->blocks()->at(block_id);
179  UpdateLivenessAtBlockEnd(block, &live);
180 
181  for (HInstruction* instr = block->end(); instr != NULL;
182  instr = instr->previous()) {
183  UpdateLivenessAtInstruction(instr, &live);
184  }
185 
186  // Reached the start of the block, do necessary bookkeeping:
187  // store computed information for this block and add predecessors
188  // to the work list as necessary.
190  first_simulate_invalid_for_index_[block_id]->CopyFrom(
192  if (live_at_block_start_[block_id]->UnionIsChanged(live)) {
193  for (int i = 0; i < block->predecessors()->length(); ++i) {
194  worklist.Add(block->predecessors()->at(i)->block_id());
195  }
196  if (block->IsInlineReturnTarget()) {
197  worklist.Add(block->inlined_entry_block()->block_id());
198  }
199  }
200  }
201  // Only collect bind/lookup instructions during the first pass.
202  collect_markers_ = false;
203  }
204 
205  // Analysis finished. Zap dead environment slots.
206  for (int i = 0; i < markers_.length(); ++i) {
208  }
209  for (int block_id = block_count_ - 1; block_id >= 0; --block_id) {
210  HBasicBlock* block = graph()->blocks()->at(block_id);
211  UpdateLivenessAtBlockEnd(block, &live);
212  ZapEnvironmentSlotsInSuccessors(block, &live);
213  }
214 
215  // Finally, remove the HEnvironment{Bind,Lookup} markers.
216  for (int i = 0; i < markers_.length(); ++i) {
217  markers_[i]->DeleteAndReplaceWith(NULL);
218  }
219 }
void UpdateLivenessAtInstruction(HInstruction *instr, BitVector *live)
void UpdateLivenessAtBlockEnd(HBasicBlock *block, BitVector *live)
void ZapEnvironmentSlotsInSuccessors(HBasicBlock *block, BitVector *live)
void ZapEnvironmentSlotsForInstruction(HEnvironmentMarker *marker)
void Set(int index, const T &element)
Definition: list-inl.h:85

References v8::internal::BitVector::Add(), block_count_, collect_markers_, v8::internal::BitVector::Contains(), DCHECK, first_simulate_, first_simulate_invalid_for_index_, v8::internal::HPhase::graph(), v8::internal::BitVector::IsEmpty(), last_simulate_, live_at_block_start_, markers_, maximum_environment_size_, NULL, v8::internal::BitVector::Remove(), v8::internal::List< T, AllocationPolicy >::Set(), UpdateLivenessAtBlockEnd(), UpdateLivenessAtInstruction(), went_live_since_last_simulate_, ZapEnvironmentSlotsForInstruction(), and ZapEnvironmentSlotsInSuccessors().

+ Here is the call graph for this function:

◆ UpdateLivenessAtBlockEnd()

void v8::internal::HEnvironmentLivenessAnalysisPhase::UpdateLivenessAtBlockEnd ( HBasicBlock *  block,
BitVector live 
)
private

Definition at line 83 of file hydrogen-environment-liveness.cc.

85  {
86  // Liveness at the end of each block: union of liveness in successors.
87  live->Clear();
88  for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
89  live->Union(*live_at_block_start_[it.Current()->block_id()]);
90  }
91 }

References v8::internal::BitVector::Clear(), live_at_block_start_, and v8::internal::BitVector::Union().

Referenced by Run().

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

◆ UpdateLivenessAtInstruction()

void v8::internal::HEnvironmentLivenessAnalysisPhase::UpdateLivenessAtInstruction ( HInstruction instr,
BitVector live 
)
private

Definition at line 94 of file hydrogen-environment-liveness.cc.

96  {
97  switch (instr->opcode()) {
98  case HValue::kEnvironmentMarker: {
99  HEnvironmentMarker* marker = HEnvironmentMarker::cast(instr);
100  int index = marker->index();
101  if (!live->Contains(index)) {
102  marker->SetFlag(HValue::kEndsLiveRange);
103  } else {
104  marker->ClearFlag(HValue::kEndsLiveRange);
105  }
107  marker->set_next_simulate(last_simulate_);
108  }
109  if (marker->kind() == HEnvironmentMarker::LOOKUP) {
110  live->Add(index);
111  } else {
112  DCHECK(marker->kind() == HEnvironmentMarker::BIND);
113  live->Remove(index);
115  }
116  if (collect_markers_) {
117  // Populate |markers_| list during the first pass.
118  markers_.Add(marker, zone());
119  }
120  break;
121  }
122  case HValue::kLeaveInlined:
123  // No environment values are live at the end of an inlined section.
124  live->Clear();
126 
127  // The following DCHECKs guard the assumption used in case
128  // kEnterInlined below:
129  DCHECK(instr->next()->IsSimulate());
130  DCHECK(instr->next()->next()->IsGoto());
131 
132  break;
133  case HValue::kEnterInlined: {
134  // Those environment values are live that are live at any return
135  // target block. Here we make use of the fact that the end of an
136  // inline sequence always looks like this: HLeaveInlined, HSimulate,
137  // HGoto (to return_target block), with no environment lookups in
138  // between (see DCHECKs above).
139  HEnterInlined* enter = HEnterInlined::cast(instr);
140  live->Clear();
141  for (int i = 0; i < enter->return_targets()->length(); ++i) {
142  int return_id = enter->return_targets()->at(i)->block_id();
143  live->Union(*live_at_block_start_[return_id]);
144  }
146  break;
147  }
148  case HValue::kSimulate:
149  last_simulate_ = HSimulate::cast(instr);
151  break;
152  default:
153  break;
154  }
155 }
bool Contains(int i) const
Definition: data-flow.h:99

References v8::internal::List< T, AllocationPolicy >::Add(), v8::internal::BitVector::Add(), v8::internal::BitVector::Clear(), collect_markers_, v8::internal::BitVector::Contains(), DCHECK, v8::internal::HValue::kEndsLiveRange, last_simulate_, live_at_block_start_, markers_, v8::internal::HInstruction::next(), NULL, v8::internal::HValue::opcode(), v8::internal::BitVector::Remove(), v8::internal::BitVector::Union(), and went_live_since_last_simulate_.

Referenced by Run().

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

◆ ZapEnvironmentSlot()

void v8::internal::HEnvironmentLivenessAnalysisPhase::ZapEnvironmentSlot ( int  index,
HSimulate *  simulate 
)
private

Definition at line 36 of file hydrogen-environment-liveness.cc.

37  {
38  int operand_index = simulate->ToOperandIndex(index);
39  if (operand_index == -1) {
40  simulate->AddAssignedValue(index, graph()->GetConstantUndefined());
41  } else {
42  simulate->SetOperandAt(operand_index, graph()->GetConstantUndefined());
43  }
44 }

References v8::internal::HPhase::graph().

Referenced by ZapEnvironmentSlotsForInstruction(), and ZapEnvironmentSlotsInSuccessors().

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

◆ ZapEnvironmentSlotsForInstruction()

void v8::internal::HEnvironmentLivenessAnalysisPhase::ZapEnvironmentSlotsForInstruction ( HEnvironmentMarker *  marker)
private

Definition at line 72 of file hydrogen-environment-liveness.cc.

73  {
74  if (!marker->CheckFlag(HValue::kEndsLiveRange)) return;
75  HSimulate* simulate = marker->next_simulate();
76  if (simulate != NULL) {
77  DCHECK(VerifyClosures(simulate->closure(), marker->closure()));
78  ZapEnvironmentSlot(marker->index(), simulate);
79  }
80 }

References DCHECK, v8::internal::HValue::kEndsLiveRange, NULL, and ZapEnvironmentSlot().

Referenced by Run().

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

◆ ZapEnvironmentSlotsInSuccessors()

void v8::internal::HEnvironmentLivenessAnalysisPhase::ZapEnvironmentSlotsInSuccessors ( HBasicBlock *  block,
BitVector live 
)
private

Definition at line 47 of file hydrogen-environment-liveness.cc.

48  {
49  // When a value is live in successor A but dead in B, we must
50  // explicitly zap it in B.
51  for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
52  HBasicBlock* successor = it.Current();
53  int successor_id = successor->block_id();
54  BitVector* live_in_successor = live_at_block_start_[successor_id];
55  if (live_in_successor->Equals(*live)) continue;
56  for (int i = 0; i < live->length(); ++i) {
57  if (!live->Contains(i)) continue;
58  if (live_in_successor->Contains(i)) continue;
59  if (first_simulate_invalid_for_index_.at(successor_id)->Contains(i)) {
60  continue;
61  }
62  HSimulate* simulate = first_simulate_.at(successor_id);
63  if (simulate == NULL) continue;
64  DCHECK(VerifyClosures(simulate->closure(),
65  block->last_environment()->closure()));
66  ZapEnvironmentSlot(i, simulate);
67  }
68  }
69 }
T & at(int i) const
Definition: list.h:69

References v8::internal::List< T, AllocationPolicy >::at(), v8::internal::BitVector::Contains(), DCHECK, v8::internal::BitVector::Equals(), first_simulate_, first_simulate_invalid_for_index_, v8::internal::BitVector::length(), live_at_block_start_, NULL, and ZapEnvironmentSlot().

Referenced by Run().

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

Member Data Documentation

◆ block_count_

int v8::internal::HEnvironmentLivenessAnalysisPhase::block_count_
private

Definition at line 39 of file hydrogen-environment-liveness.h.

Referenced by HEnvironmentLivenessAnalysisPhase(), and Run().

◆ collect_markers_

bool v8::internal::HEnvironmentLivenessAnalysisPhase::collect_markers_
private

Definition at line 54 of file hydrogen-environment-liveness.h.

Referenced by Run(), and UpdateLivenessAtInstruction().

◆ first_simulate_

ZoneList<HSimulate*> v8::internal::HEnvironmentLivenessAnalysisPhase::first_simulate_
private

◆ first_simulate_invalid_for_index_

ZoneList<BitVector*> v8::internal::HEnvironmentLivenessAnalysisPhase::first_simulate_invalid_for_index_
private

◆ last_simulate_

HSimulate* v8::internal::HEnvironmentLivenessAnalysisPhase::last_simulate_
private

Definition at line 59 of file hydrogen-environment-liveness.h.

Referenced by Run(), and UpdateLivenessAtInstruction().

◆ live_at_block_start_

ZoneList<BitVector*> v8::internal::HEnvironmentLivenessAnalysisPhase::live_at_block_start_
private

◆ markers_

ZoneList<HEnvironmentMarker*> v8::internal::HEnvironmentLivenessAnalysisPhase::markers_
private

Definition at line 53 of file hydrogen-environment-liveness.h.

Referenced by Run(), and UpdateLivenessAtInstruction().

◆ maximum_environment_size_

int v8::internal::HEnvironmentLivenessAnalysisPhase::maximum_environment_size_
private

Definition at line 43 of file hydrogen-environment-liveness.h.

Referenced by HEnvironmentLivenessAnalysisPhase(), and Run().

◆ went_live_since_last_simulate_

BitVector v8::internal::HEnvironmentLivenessAnalysisPhase::went_live_since_last_simulate_
private

Definition at line 60 of file hydrogen-environment-liveness.h.

Referenced by Run(), and UpdateLivenessAtInstruction().


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