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

#include <register-allocator.h>

+ Inheritance diagram for v8::internal::compiler::LiveRange:
+ Collaboration diagram for v8::internal::compiler::LiveRange:

Public Member Functions

 LiveRange (int id, Zone *zone)
 
UseIntervalfirst_interval () const
 
UsePositionfirst_pos () const
 
LiveRangeparent () const
 
LiveRangeTopLevel ()
 
LiveRangenext () const
 
bool IsChild () const
 
int id () const
 
bool IsFixed () const
 
bool IsEmpty () const
 
InstructionOperandCreateAssignedOperand (Zone *zone)
 
int assigned_register () const
 
int spill_start_index () const
 
void set_assigned_register (int reg, Zone *zone)
 
void MakeSpilled (Zone *zone)
 
bool is_phi () const
 
void set_is_phi (bool is_phi)
 
bool is_non_loop_phi () const
 
void set_is_non_loop_phi (bool is_non_loop_phi)
 
UsePositionNextUsePosition (LifetimePosition start)
 
UsePositionNextRegisterPosition (LifetimePosition start)
 
UsePositionNextUsePositionRegisterIsBeneficial (LifetimePosition start)
 
UsePositionPreviousUsePositionRegisterIsBeneficial (LifetimePosition start)
 
bool CanBeSpilled (LifetimePosition pos)
 
void SplitAt (LifetimePosition position, LiveRange *result, Zone *zone)
 
RegisterKind Kind () const
 
bool HasRegisterAssigned () const
 
bool IsSpilled () const
 
InstructionOperandcurrent_hint_operand () const
 
InstructionOperandFirstHint () const
 
LifetimePosition Start () const
 
LifetimePosition End () const
 
bool HasAllocatedSpillOperand () const
 
InstructionOperandGetSpillOperand () const
 
void SetSpillOperand (InstructionOperand *operand)
 
void SetSpillStartIndex (int start)
 
bool ShouldBeAllocatedBefore (const LiveRange *other) const
 
bool CanCover (LifetimePosition position) const
 
bool Covers (LifetimePosition position)
 
LifetimePosition FirstIntersection (LiveRange *other)
 
void EnsureInterval (LifetimePosition start, LifetimePosition end, Zone *zone)
 
void AddUseInterval (LifetimePosition start, LifetimePosition end, Zone *zone)
 
void AddUsePosition (LifetimePosition pos, InstructionOperand *operand, InstructionOperand *hint, Zone *zone)
 
void ShortenTo (LifetimePosition start)
 
- Public Member Functions inherited from v8::internal::ZoneObject
 INLINE (void *operator new(size_t size, Zone *zone))
 
void operator delete (void *, size_t)
 
void operator delete (void *pointer, Zone *zone)
 

Static Public Attributes

static const int kInvalidAssignment = 0x7fffffff
 

Private Member Functions

void ConvertOperands (Zone *zone)
 
UseIntervalFirstSearchIntervalForPosition (LifetimePosition position) const
 
void AdvanceLastProcessedMarker (UseInterval *to_start_of, LifetimePosition but_not_past) const
 

Private Attributes

int id_
 
bool spilled_
 
bool is_phi_
 
bool is_non_loop_phi_
 
RegisterKind kind_
 
int assigned_register_
 
UseIntervallast_interval_
 
UseIntervalfirst_interval_
 
UsePositionfirst_pos_
 
LiveRangeparent_
 
LiveRangenext_
 
UseIntervalcurrent_interval_
 
UsePositionlast_processed_use_
 
InstructionOperandcurrent_hint_operand_
 
InstructionOperandspill_operand_
 
int spill_start_index_
 

Friends

class RegisterAllocator
 

Detailed Description

Definition at line 181 of file register-allocator.h.

Constructor & Destructor Documentation

◆ LiveRange()

v8::internal::compiler::LiveRange::LiveRange ( int  id,
Zone zone 
)

Definition at line 92 of file register-allocator.cc.

93  : id_(id),
94  spilled_(false),
95  is_phi_(false),
96  is_non_loop_phi_(false),
101  first_pos_(NULL),
102  parent_(NULL),
103  next_(NULL),
107  spill_operand_(new (zone) InstructionOperand()),
InstructionOperand * current_hint_operand_
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
const int kMaxInt
Definition: globals.h:109

Member Function Documentation

◆ AddUseInterval()

void v8::internal::compiler::LiveRange::AddUseInterval ( LifetimePosition  start,
LifetimePosition  end,
Zone zone 
)

Definition at line 383 of file register-allocator.cc.

384  {
385  RegisterAllocator::TraceAlloc("Add to live range %d interval [%d %d[\n", id_,
386  start.Value(), end.Value());
387  if (first_interval_ == NULL) {
388  UseInterval* interval = new (zone) UseInterval(start, end);
389  first_interval_ = interval;
390  last_interval_ = interval;
391  } else {
392  if (end.Value() == first_interval_->start().Value()) {
393  first_interval_->set_start(start);
394  } else if (end.Value() < first_interval_->start().Value()) {
395  UseInterval* interval = new (zone) UseInterval(start, end);
396  interval->set_next(first_interval_);
397  first_interval_ = interval;
398  } else {
399  // Order of instruction's processing (see ProcessInstructions) guarantees
400  // that each new use interval either precedes or intersects with
401  // last added interval.
402  DCHECK(start.Value() < first_interval_->end().Value());
405  }
406  }
407 }
void set_start(LifetimePosition start)
#define DCHECK(condition)
Definition: logging.h:205
static LifetimePosition Max(LifetimePosition a, LifetimePosition b)
static LifetimePosition Min(LifetimePosition a, LifetimePosition b)

References DCHECK, v8::internal::compiler::UseInterval::end(), v8::internal::compiler::UseInterval::end_, first_interval_, id_, last_interval_, v8::internal::compiler::Max(), v8::internal::compiler::Min(), NULL, v8::internal::compiler::UseInterval::set_next(), v8::internal::compiler::UseInterval::set_start(), v8::internal::compiler::UseInterval::start(), v8::internal::compiler::UseInterval::start_, and v8::internal::compiler::LifetimePosition::Value().

+ Here is the call graph for this function:

◆ AddUsePosition()

void v8::internal::compiler::LiveRange::AddUsePosition ( LifetimePosition  pos,
InstructionOperand operand,
InstructionOperand hint,
Zone zone 
)

Definition at line 410 of file register-allocator.cc.

412  {
413  RegisterAllocator::TraceAlloc("Add to live range %d use position %d\n", id_,
414  pos.Value());
415  UsePosition* use_pos = new (zone) UsePosition(pos, operand, hint);
416  UsePosition* prev_hint = NULL;
417  UsePosition* prev = NULL;
418  UsePosition* current = first_pos_;
419  while (current != NULL && current->pos().Value() < pos.Value()) {
420  prev_hint = current->HasHint() ? current : prev_hint;
421  prev = current;
422  current = current->next();
423  }
424 
425  if (prev == NULL) {
426  use_pos->set_next(first_pos_);
427  first_pos_ = use_pos;
428  } else {
429  use_pos->next_ = prev->next_;
430  prev->next_ = use_pos;
431  }
432 
433  if (prev_hint == NULL && use_pos->HasHint()) {
434  current_hint_operand_ = hint;
435  }
436 }

References current_hint_operand_, first_pos_, v8::internal::compiler::UsePosition::HasHint(), id_, v8::internal::compiler::UsePosition::next(), v8::internal::compiler::UsePosition::next_, NULL, v8::internal::compiler::UsePosition::pos(), v8::internal::compiler::UsePosition::set_next(), and v8::internal::compiler::LifetimePosition::Value().

+ Here is the call graph for this function:

◆ AdvanceLastProcessedMarker()

void v8::internal::compiler::LiveRange::AdvanceLastProcessedMarker ( UseInterval to_start_of,
LifetimePosition  but_not_past 
) const
private

Definition at line 232 of file register-allocator.cc.

233  {
234  if (to_start_of == NULL) return;
235  if (to_start_of->start().Value() > but_not_past.Value()) return;
236  LifetimePosition start = current_interval_ == NULL
238  : current_interval_->start();
239  if (to_start_of->start().Value() > start.Value()) {
240  current_interval_ = to_start_of;
241  }
242 }

References current_interval_, v8::internal::compiler::LifetimePosition::Invalid(), NULL, v8::internal::compiler::UseInterval::start(), and v8::internal::compiler::LifetimePosition::Value().

Referenced by Covers(), and FirstIntersection().

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

◆ assigned_register()

int v8::internal::compiler::LiveRange::assigned_register ( ) const
inline

Definition at line 197 of file register-allocator.h.

197 { return assigned_register_; }

References assigned_register_.

Referenced by CreateAssignedOperand().

+ Here is the caller graph for this function:

◆ CanBeSpilled()

bool v8::internal::compiler::LiveRange::CanBeSpilled ( LifetimePosition  pos)

Definition at line 183 of file register-allocator.cc.

183  {
184  // We cannot spill a live range that has a use requiring a register
185  // at the current or the immediate next position.
186  UsePosition* use_pos = NextRegisterPosition(pos);
187  if (use_pos == NULL) return true;
188  return use_pos->pos().Value() >
189  pos.NextInstruction().InstructionEnd().Value();
190 }
UsePosition * NextRegisterPosition(LifetimePosition start)

References v8::internal::compiler::LifetimePosition::InstructionEnd(), v8::internal::compiler::LifetimePosition::NextInstruction(), NextRegisterPosition(), NULL, v8::internal::compiler::UsePosition::pos(), and v8::internal::compiler::LifetimePosition::Value().

+ Here is the call graph for this function:

◆ CanCover()

bool v8::internal::compiler::LiveRange::CanCover ( LifetimePosition  position) const

Definition at line 456 of file register-allocator.cc.

456  {
457  if (IsEmpty()) return false;
458  return Start().Value() <= position.Value() &&
459  position.Value() < End().Value();
460 }

References End(), IsEmpty(), Start(), and v8::internal::compiler::LifetimePosition::Value().

Referenced by Covers().

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

◆ ConvertOperands()

void v8::internal::compiler::LiveRange::ConvertOperands ( Zone zone)
private

Definition at line 439 of file register-allocator.cc.

439  {
440  InstructionOperand* op = CreateAssignedOperand(zone);
441  UsePosition* use_pos = first_pos();
442  while (use_pos != NULL) {
443  DCHECK(Start().Value() <= use_pos->pos().Value() &&
444  use_pos->pos().Value() <= End().Value());
445 
446  if (use_pos->HasOperand()) {
447  DCHECK(op->IsRegister() || op->IsDoubleRegister() ||
448  !use_pos->RequiresRegister());
449  use_pos->operand()->ConvertTo(op->kind(), op->index());
450  }
451  use_pos = use_pos->next();
452  }
453 }
InstructionOperand * CreateAssignedOperand(Zone *zone)

References v8::internal::compiler::InstructionOperand::ConvertTo(), CreateAssignedOperand(), DCHECK, End(), first_pos(), v8::internal::compiler::UsePosition::HasOperand(), v8::internal::compiler::InstructionOperand::index(), v8::internal::compiler::InstructionOperand::kind(), v8::internal::compiler::UsePosition::next(), NULL, v8::internal::compiler::UsePosition::operand(), v8::internal::compiler::UsePosition::pos(), v8::internal::compiler::UsePosition::RequiresRegister(), Start(), and v8::internal::compiler::LifetimePosition::Value().

Referenced by MakeSpilled(), and set_assigned_register().

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

◆ Covers()

bool v8::internal::compiler::LiveRange::Covers ( LifetimePosition  position)

Definition at line 463 of file register-allocator.cc.

463  {
464  if (!CanCover(position)) return false;
465  UseInterval* start_search = FirstSearchIntervalForPosition(position);
466  for (UseInterval* interval = start_search; interval != NULL;
467  interval = interval->next()) {
468  DCHECK(interval->next() == NULL ||
469  interval->next()->start().Value() >= interval->start().Value());
470  AdvanceLastProcessedMarker(interval, position);
471  if (interval->Contains(position)) return true;
472  if (interval->start().Value() > position.Value()) return false;
473  }
474  return false;
475 }
bool CanCover(LifetimePosition position) const
void AdvanceLastProcessedMarker(UseInterval *to_start_of, LifetimePosition but_not_past) const
UseInterval * FirstSearchIntervalForPosition(LifetimePosition position) const

References AdvanceLastProcessedMarker(), CanCover(), DCHECK, FirstSearchIntervalForPosition(), NULL, and v8::internal::compiler::LifetimePosition::Value().

+ Here is the call graph for this function:

◆ CreateAssignedOperand()

InstructionOperand * v8::internal::compiler::LiveRange::CreateAssignedOperand ( Zone zone)

Definition at line 193 of file register-allocator.cc.

193  {
194  InstructionOperand* op = NULL;
195  if (HasRegisterAssigned()) {
196  DCHECK(!IsSpilled());
197  switch (Kind()) {
198  case GENERAL_REGISTERS:
199  op = RegisterOperand::Create(assigned_register(), zone);
200  break;
201  case DOUBLE_REGISTERS:
202  op = DoubleRegisterOperand::Create(assigned_register(), zone);
203  break;
204  default:
205  UNREACHABLE();
206  }
207  } else if (IsSpilled()) {
209  op = TopLevel()->GetSpillOperand();
210  DCHECK(!op->IsUnallocated());
211  } else {
212  UnallocatedOperand* unalloc =
213  new (zone) UnallocatedOperand(UnallocatedOperand::NONE);
214  unalloc->set_virtual_register(id_);
215  op = unalloc;
216  }
217  return op;
218 }
InstructionOperand * GetSpillOperand() const
#define UNREACHABLE()
Definition: logging.h:30

References assigned_register(), DCHECK, v8::internal::compiler::DOUBLE_REGISTERS, v8::internal::compiler::GENERAL_REGISTERS, GetSpillOperand(), HasRegisterAssigned(), id_, IsSpilled(), Kind(), v8::internal::compiler::UnallocatedOperand::NONE, NULL, v8::internal::compiler::UnallocatedOperand::set_virtual_register(), TopLevel(), and UNREACHABLE.

Referenced by ConvertOperands().

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

◆ current_hint_operand()

InstructionOperand* v8::internal::compiler::LiveRange::current_hint_operand ( ) const
inline

Definition at line 242 of file register-allocator.h.

242  {
244  return current_hint_operand_;
245  }
InstructionOperand * FirstHint() const

References current_hint_operand_, DCHECK, and FirstHint().

+ Here is the call graph for this function:

◆ End()

LifetimePosition v8::internal::compiler::LiveRange::End ( ) const
inline

Definition at line 258 of file register-allocator.h.

258  {
259  DCHECK(!IsEmpty());
260  return last_interval_->end();
261  }

References DCHECK, v8::internal::compiler::UseInterval::end(), IsEmpty(), and last_interval_.

Referenced by CanCover(), ConvertOperands(), and FirstIntersection().

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

◆ EnsureInterval()

void v8::internal::compiler::LiveRange::EnsureInterval ( LifetimePosition  start,
LifetimePosition  end,
Zone zone 
)

Definition at line 361 of file register-allocator.cc.

362  {
363  RegisterAllocator::TraceAlloc("Ensure live range %d in interval [%d %d[\n",
364  id_, start.Value(), end.Value());
365  LifetimePosition new_end = end;
366  while (first_interval_ != NULL &&
367  first_interval_->start().Value() <= end.Value()) {
368  if (first_interval_->end().Value() > end.Value()) {
369  new_end = first_interval_->end();
370  }
372  }
373 
374  UseInterval* new_interval = new (zone) UseInterval(start, new_end);
375  new_interval->next_ = first_interval_;
376  first_interval_ = new_interval;
377  if (new_interval->next() == NULL) {
378  last_interval_ = new_interval;
379  }
380 }

References v8::internal::compiler::UseInterval::end(), first_interval_, id_, last_interval_, v8::internal::compiler::UseInterval::next(), v8::internal::compiler::UseInterval::next_, NULL, v8::internal::compiler::UseInterval::start(), and v8::internal::compiler::LifetimePosition::Value().

+ Here is the call graph for this function:

◆ first_interval()

UseInterval* v8::internal::compiler::LiveRange::first_interval ( ) const
inline

Definition at line 187 of file register-allocator.h.

187 { return first_interval_; }

References first_interval_.

Referenced by FirstIntersection(), IsEmpty(), and Start().

+ Here is the caller graph for this function:

◆ first_pos()

UsePosition* v8::internal::compiler::LiveRange::first_pos ( ) const
inline

Definition at line 188 of file register-allocator.h.

188 { return first_pos_; }

References first_pos_.

Referenced by ConvertOperands(), NextUsePosition(), PreviousUsePositionRegisterIsBeneficial(), and ShouldBeAllocatedBefore().

+ Here is the caller graph for this function:

◆ FirstHint()

InstructionOperand* v8::internal::compiler::LiveRange::FirstHint ( ) const
inline

Definition at line 246 of file register-allocator.h.

246  {
247  UsePosition* pos = first_pos_;
248  while (pos != NULL && !pos->HasHint()) pos = pos->next();
249  if (pos != NULL) return pos->hint();
250  return NULL;
251  }
InstructionOperand * hint() const

References first_pos_, v8::internal::compiler::UsePosition::HasHint(), v8::internal::compiler::UsePosition::hint(), v8::internal::compiler::UsePosition::next(), and NULL.

Referenced by current_hint_operand().

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

◆ FirstIntersection()

LifetimePosition v8::internal::compiler::LiveRange::FirstIntersection ( LiveRange other)

Definition at line 478 of file register-allocator.cc.

478  {
479  UseInterval* b = other->first_interval();
480  if (b == NULL) return LifetimePosition::Invalid();
481  LifetimePosition advance_last_processed_up_to = b->start();
482  UseInterval* a = FirstSearchIntervalForPosition(b->start());
483  while (a != NULL && b != NULL) {
484  if (a->start().Value() > other->End().Value()) break;
485  if (b->start().Value() > End().Value()) break;
486  LifetimePosition cur_intersection = a->Intersect(b);
487  if (cur_intersection.IsValid()) {
488  return cur_intersection;
489  }
490  if (a->start().Value() < b->start().Value()) {
491  a = a->next();
492  if (a == NULL || a->start().Value() > other->End().Value()) break;
493  AdvanceLastProcessedMarker(a, advance_last_processed_up_to);
494  } else {
495  b = b->next();
496  }
497  }
498  return LifetimePosition::Invalid();
499 }

References AdvanceLastProcessedMarker(), End(), first_interval(), FirstSearchIntervalForPosition(), v8::internal::compiler::UseInterval::Intersect(), v8::internal::compiler::LifetimePosition::Invalid(), v8::internal::compiler::LifetimePosition::IsValid(), v8::internal::compiler::UseInterval::next(), NULL, v8::internal::compiler::UseInterval::start(), and v8::internal::compiler::LifetimePosition::Value().

+ Here is the call graph for this function:

◆ FirstSearchIntervalForPosition()

UseInterval * v8::internal::compiler::LiveRange::FirstSearchIntervalForPosition ( LifetimePosition  position) const
private

Definition at line 221 of file register-allocator.cc.

222  {
223  if (current_interval_ == NULL) return first_interval_;
224  if (current_interval_->start().Value() > position.Value()) {
226  return first_interval_;
227  }
228  return current_interval_;
229 }

References current_interval_, first_interval_, NULL, v8::internal::compiler::UseInterval::start(), and v8::internal::compiler::LifetimePosition::Value().

Referenced by Covers(), FirstIntersection(), and SplitAt().

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

◆ GetSpillOperand()

InstructionOperand* v8::internal::compiler::LiveRange::GetSpillOperand ( ) const
inline

Definition at line 264 of file register-allocator.h.

264 { return spill_operand_; }

References spill_operand_.

Referenced by CreateAssignedOperand().

+ Here is the caller graph for this function:

◆ HasAllocatedSpillOperand()

bool v8::internal::compiler::LiveRange::HasAllocatedSpillOperand ( ) const

Definition at line 127 of file register-allocator.cc.

127  {
129  return !spill_operand_->IsIgnored();
130 }

References DCHECK, NULL, and spill_operand_.

Referenced by MakeSpilled().

+ Here is the caller graph for this function:

◆ HasRegisterAssigned()

bool v8::internal::compiler::LiveRange::HasRegisterAssigned ( ) const
inline

Definition at line 237 of file register-allocator.h.

237  {
239  }

References assigned_register_, and kInvalidAssignment.

Referenced by CreateAssignedOperand(), and set_assigned_register().

+ Here is the caller graph for this function:

◆ id()

int v8::internal::compiler::LiveRange::id ( ) const
inline

Definition at line 193 of file register-allocator.h.

193 { return id_; }

References id_.

◆ is_non_loop_phi()

bool v8::internal::compiler::LiveRange::is_non_loop_phi ( ) const
inline

Definition at line 203 of file register-allocator.h.

203 { return is_non_loop_phi_; }

References is_non_loop_phi_.

Referenced by set_is_non_loop_phi().

+ Here is the caller graph for this function:

◆ is_phi()

bool v8::internal::compiler::LiveRange::is_phi ( ) const
inline

Definition at line 201 of file register-allocator.h.

201 { return is_phi_; }

References is_phi_.

Referenced by set_is_phi().

+ Here is the caller graph for this function:

◆ IsChild()

bool v8::internal::compiler::LiveRange::IsChild ( ) const
inline

Definition at line 192 of file register-allocator.h.

192 { return parent() != NULL; }

References NULL, and parent().

+ Here is the call graph for this function:

◆ IsEmpty()

bool v8::internal::compiler::LiveRange::IsEmpty ( ) const
inline

Definition at line 195 of file register-allocator.h.

195 { return first_interval() == NULL; }

References first_interval(), and NULL.

Referenced by CanCover(), End(), SplitAt(), and Start().

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

◆ IsFixed()

bool v8::internal::compiler::LiveRange::IsFixed ( ) const
inline

Definition at line 194 of file register-allocator.h.

194 { return id_ < 0; }

References id_.

◆ IsSpilled()

bool v8::internal::compiler::LiveRange::IsSpilled ( ) const
inline

Definition at line 240 of file register-allocator.h.

240 { return spilled_; }

References spilled_.

Referenced by CreateAssignedOperand(), MakeSpilled(), and set_assigned_register().

+ Here is the caller graph for this function:

◆ Kind()

RegisterKind v8::internal::compiler::LiveRange::Kind ( ) const
inline

Definition at line 236 of file register-allocator.h.

236 { return kind_; }

References kind_.

Referenced by CreateAssignedOperand().

+ Here is the caller graph for this function:

◆ MakeSpilled()

void v8::internal::compiler::LiveRange::MakeSpilled ( Zone zone)

Definition at line 118 of file register-allocator.cc.

References assigned_register_, ConvertOperands(), DCHECK, HasAllocatedSpillOperand(), IsSpilled(), kInvalidAssignment, spilled_, and TopLevel().

+ Here is the call graph for this function:

◆ next()

LiveRange* v8::internal::compiler::LiveRange::next ( ) const
inline

Definition at line 191 of file register-allocator.h.

191 { return next_; }

References next_.

Referenced by SplitAt().

+ Here is the caller graph for this function:

◆ NextRegisterPosition()

UsePosition * v8::internal::compiler::LiveRange::NextRegisterPosition ( LifetimePosition  start)

Definition at line 174 of file register-allocator.cc.

174  {
175  UsePosition* pos = NextUsePosition(start);
176  while (pos != NULL && !pos->RequiresRegister()) {
177  pos = pos->next();
178  }
179  return pos;
180 }
UsePosition * NextUsePosition(LifetimePosition start)

References v8::internal::compiler::UsePosition::next(), NextUsePosition(), NULL, and v8::internal::compiler::UsePosition::RequiresRegister().

Referenced by CanBeSpilled().

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

◆ NextUsePosition()

UsePosition * v8::internal::compiler::LiveRange::NextUsePosition ( LifetimePosition  start)

Definition at line 141 of file register-allocator.cc.

141  {
142  UsePosition* use_pos = last_processed_use_;
143  if (use_pos == NULL) use_pos = first_pos();
144  while (use_pos != NULL && use_pos->pos().Value() < start.Value()) {
145  use_pos = use_pos->next();
146  }
147  last_processed_use_ = use_pos;
148  return use_pos;
149 }

References first_pos(), last_processed_use_, v8::internal::compiler::UsePosition::next(), NULL, v8::internal::compiler::UsePosition::pos(), and v8::internal::compiler::LifetimePosition::Value().

Referenced by NextRegisterPosition(), and NextUsePositionRegisterIsBeneficial().

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

◆ NextUsePositionRegisterIsBeneficial()

UsePosition * v8::internal::compiler::LiveRange::NextUsePositionRegisterIsBeneficial ( LifetimePosition  start)

Definition at line 152 of file register-allocator.cc.

153  {
154  UsePosition* pos = NextUsePosition(start);
155  while (pos != NULL && !pos->RegisterIsBeneficial()) {
156  pos = pos->next();
157  }
158  return pos;
159 }

References v8::internal::compiler::UsePosition::next(), NextUsePosition(), NULL, and v8::internal::compiler::UsePosition::RegisterIsBeneficial().

+ Here is the call graph for this function:

◆ parent()

LiveRange* v8::internal::compiler::LiveRange::parent ( ) const
inline

Definition at line 189 of file register-allocator.h.

189 { return parent_; }

References parent_.

Referenced by IsChild().

+ Here is the caller graph for this function:

◆ PreviousUsePositionRegisterIsBeneficial()

UsePosition * v8::internal::compiler::LiveRange::PreviousUsePositionRegisterIsBeneficial ( LifetimePosition  start)

Definition at line 162 of file register-allocator.cc.

163  {
164  UsePosition* pos = first_pos();
165  UsePosition* prev = NULL;
166  while (pos != NULL && pos->pos().Value() < start.Value()) {
167  if (pos->RegisterIsBeneficial()) prev = pos;
168  pos = pos->next();
169  }
170  return prev;
171 }

References first_pos(), v8::internal::compiler::UsePosition::next(), NULL, v8::internal::compiler::UsePosition::pos(), v8::internal::compiler::UsePosition::RegisterIsBeneficial(), and v8::internal::compiler::LifetimePosition::Value().

+ Here is the call graph for this function:

◆ set_assigned_register()

void v8::internal::compiler::LiveRange::set_assigned_register ( int  reg,
Zone zone 
)

Definition at line 111 of file register-allocator.cc.

111  {
113  assigned_register_ = reg;
114  ConvertOperands(zone);
115 }

References assigned_register_, ConvertOperands(), DCHECK, HasRegisterAssigned(), and IsSpilled().

+ Here is the call graph for this function:

◆ set_is_non_loop_phi()

void v8::internal::compiler::LiveRange::set_is_non_loop_phi ( bool  is_non_loop_phi)
inline

Definition at line 204 of file register-allocator.h.

References is_non_loop_phi(), and is_non_loop_phi_.

+ Here is the call graph for this function:

◆ set_is_phi()

void v8::internal::compiler::LiveRange::set_is_phi ( bool  is_phi)
inline

Definition at line 202 of file register-allocator.h.

References is_phi(), and is_phi_.

+ Here is the call graph for this function:

◆ SetSpillOperand()

void v8::internal::compiler::LiveRange::SetSpillOperand ( InstructionOperand operand)

Definition at line 133 of file register-allocator.cc.

133  {
134  DCHECK(!operand->IsUnallocated());
136  DCHECK(spill_operand_->IsIgnored());
137  spill_operand_->ConvertTo(operand->kind(), operand->index());
138 }
void ConvertTo(Kind kind, int index)
Definition: instruction.h:75

References v8::internal::compiler::InstructionOperand::ConvertTo(), DCHECK, v8::internal::compiler::InstructionOperand::index(), v8::internal::compiler::InstructionOperand::kind(), NULL, and spill_operand_.

+ Here is the call graph for this function:

◆ SetSpillStartIndex()

void v8::internal::compiler::LiveRange::SetSpillStartIndex ( int  start)
inline

Definition at line 267 of file register-allocator.h.

267  {
269  }

References v8::internal::compiler::Min(), and spill_start_index_.

+ Here is the call graph for this function:

◆ ShortenTo()

void v8::internal::compiler::LiveRange::ShortenTo ( LifetimePosition  start)

Definition at line 351 of file register-allocator.cc.

351  {
352  RegisterAllocator::TraceAlloc("Shorten live range %d to [%d\n", id_,
353  start.Value());
355  DCHECK(first_interval_->start().Value() <= start.Value());
356  DCHECK(start.Value() < first_interval_->end().Value());
357  first_interval_->set_start(start);
358 }

References DCHECK, v8::internal::compiler::UseInterval::end(), first_interval_, id_, NULL, v8::internal::compiler::UseInterval::set_start(), v8::internal::compiler::UseInterval::start(), and v8::internal::compiler::LifetimePosition::Value().

+ Here is the call graph for this function:

◆ ShouldBeAllocatedBefore()

bool v8::internal::compiler::LiveRange::ShouldBeAllocatedBefore ( const LiveRange other) const

Definition at line 337 of file register-allocator.cc.

337  {
338  LifetimePosition start = Start();
339  LifetimePosition other_start = other->Start();
340  if (start.Value() == other_start.Value()) {
341  UsePosition* pos = first_pos();
342  if (pos == NULL) return false;
343  UsePosition* other_pos = other->first_pos();
344  if (other_pos == NULL) return true;
345  return pos->pos().Value() < other_pos->pos().Value();
346  }
347  return start.Value() < other_start.Value();
348 }

References first_pos(), NULL, v8::internal::compiler::UsePosition::pos(), Start(), and v8::internal::compiler::LifetimePosition::Value().

+ Here is the call graph for this function:

◆ spill_start_index()

int v8::internal::compiler::LiveRange::spill_start_index ( ) const
inline

Definition at line 198 of file register-allocator.h.

198 { return spill_start_index_; }

References spill_start_index_.

◆ SplitAt()

void v8::internal::compiler::LiveRange::SplitAt ( LifetimePosition  position,
LiveRange result,
Zone zone 
)

Definition at line 245 of file register-allocator.cc.

246  {
247  DCHECK(Start().Value() < position.Value());
248  DCHECK(result->IsEmpty());
249  // Find the last interval that ends before the position. If the
250  // position is contained in one of the intervals in the chain, we
251  // split that interval and use the first part.
252  UseInterval* current = FirstSearchIntervalForPosition(position);
253 
254  // If the split position coincides with the beginning of a use interval
255  // we need to split use positons in a special way.
256  bool split_at_start = false;
257 
258  if (current->start().Value() == position.Value()) {
259  // When splitting at start we need to locate the previous use interval.
260  current = first_interval_;
261  }
262 
263  while (current != NULL) {
264  if (current->Contains(position)) {
265  current->SplitAt(position, zone);
266  break;
267  }
268  UseInterval* next = current->next();
269  if (next->start().Value() >= position.Value()) {
270  split_at_start = (next->start().Value() == position.Value());
271  break;
272  }
273  current = next;
274  }
275 
276  // Partition original use intervals to the two live ranges.
277  UseInterval* before = current;
278  UseInterval* after = before->next();
279  result->last_interval_ =
280  (last_interval_ == before)
281  ? after // Only interval in the range after split.
282  : last_interval_; // Last interval of the original range.
283  result->first_interval_ = after;
284  last_interval_ = before;
285 
286  // Find the last use position before the split and the first use
287  // position after it.
288  UsePosition* use_after = first_pos_;
289  UsePosition* use_before = NULL;
290  if (split_at_start) {
291  // The split position coincides with the beginning of a use interval (the
292  // end of a lifetime hole). Use at this position should be attributed to
293  // the split child because split child owns use interval covering it.
294  while (use_after != NULL && use_after->pos().Value() < position.Value()) {
295  use_before = use_after;
296  use_after = use_after->next();
297  }
298  } else {
299  while (use_after != NULL && use_after->pos().Value() <= position.Value()) {
300  use_before = use_after;
301  use_after = use_after->next();
302  }
303  }
304 
305  // Partition original use positions to the two live ranges.
306  if (use_before != NULL) {
307  use_before->next_ = NULL;
308  } else {
309  first_pos_ = NULL;
310  }
311  result->first_pos_ = use_after;
312 
313  // Discard cached iteration state. It might be pointing
314  // to the use that no longer belongs to this live range.
317 
318  // Link the new live range in the chain before any of the other
319  // ranges linked from the range before the split.
320  result->parent_ = (parent_ == NULL) ? this : parent_;
321  result->kind_ = result->parent_->kind_;
322  result->next_ = next_;
323  next_ = result;
324 
325 #ifdef DEBUG
326  Verify();
327  result->Verify();
328 #endif
329 }
void SplitAt(LifetimePosition pos, Zone *zone)

References v8::internal::compiler::UseInterval::Contains(), current_interval_, DCHECK, first_interval_, first_pos_, FirstSearchIntervalForPosition(), IsEmpty(), kind_, last_interval_, last_processed_use_, v8::internal::compiler::UseInterval::next(), v8::internal::compiler::UsePosition::next(), next(), v8::internal::compiler::UsePosition::next_, next_, NULL, parent_, v8::internal::compiler::UsePosition::pos(), v8::internal::compiler::UseInterval::SplitAt(), v8::internal::compiler::UseInterval::start(), Start(), and v8::internal::compiler::LifetimePosition::Value().

+ Here is the call graph for this function:

◆ Start()

LifetimePosition v8::internal::compiler::LiveRange::Start ( ) const
inline

Definition at line 253 of file register-allocator.h.

253  {
254  DCHECK(!IsEmpty());
255  return first_interval()->start();
256  }

References DCHECK, first_interval(), IsEmpty(), and v8::internal::compiler::UseInterval::start().

Referenced by CanCover(), ConvertOperands(), ShouldBeAllocatedBefore(), and SplitAt().

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

◆ TopLevel()

LiveRange* v8::internal::compiler::LiveRange::TopLevel ( )
inline

Definition at line 190 of file register-allocator.h.

190 { return (parent_ == NULL) ? this : parent_; }

References NULL, and parent_.

Referenced by CreateAssignedOperand(), and MakeSpilled().

+ Here is the caller graph for this function:

Friends And Related Function Documentation

◆ RegisterAllocator

friend class RegisterAllocator
friend

Definition at line 316 of file register-allocator.h.

Member Data Documentation

◆ assigned_register_

int v8::internal::compiler::LiveRange::assigned_register_
private

◆ current_hint_operand_

InstructionOperand* v8::internal::compiler::LiveRange::current_hint_operand_
private

Definition at line 312 of file register-allocator.h.

Referenced by AddUsePosition(), and current_hint_operand().

◆ current_interval_

UseInterval* v8::internal::compiler::LiveRange::current_interval_
mutableprivate

◆ first_interval_

UseInterval* v8::internal::compiler::LiveRange::first_interval_
private

◆ first_pos_

UsePosition* v8::internal::compiler::LiveRange::first_pos_
private

Definition at line 305 of file register-allocator.h.

Referenced by AddUsePosition(), first_pos(), FirstHint(), and SplitAt().

◆ id_

int v8::internal::compiler::LiveRange::id_
private

◆ is_non_loop_phi_

bool v8::internal::compiler::LiveRange::is_non_loop_phi_
private

Definition at line 300 of file register-allocator.h.

Referenced by is_non_loop_phi(), and set_is_non_loop_phi().

◆ is_phi_

bool v8::internal::compiler::LiveRange::is_phi_
private

Definition at line 299 of file register-allocator.h.

Referenced by is_phi(), and set_is_phi().

◆ kind_

RegisterKind v8::internal::compiler::LiveRange::kind_
private

Definition at line 301 of file register-allocator.h.

Referenced by Kind(), and SplitAt().

◆ kInvalidAssignment

const int v8::internal::compiler::LiveRange::kInvalidAssignment = 0x7fffffff
static

Definition at line 183 of file register-allocator.h.

Referenced by HasRegisterAssigned(), and MakeSpilled().

◆ last_interval_

UseInterval* v8::internal::compiler::LiveRange::last_interval_
private

Definition at line 303 of file register-allocator.h.

Referenced by AddUseInterval(), End(), EnsureInterval(), and SplitAt().

◆ last_processed_use_

UsePosition* v8::internal::compiler::LiveRange::last_processed_use_
private

Definition at line 310 of file register-allocator.h.

Referenced by NextUsePosition(), and SplitAt().

◆ next_

LiveRange* v8::internal::compiler::LiveRange::next_
private

Definition at line 307 of file register-allocator.h.

Referenced by next(), and SplitAt().

◆ parent_

LiveRange* v8::internal::compiler::LiveRange::parent_
private

Definition at line 306 of file register-allocator.h.

Referenced by parent(), SplitAt(), and TopLevel().

◆ spill_operand_

InstructionOperand* v8::internal::compiler::LiveRange::spill_operand_
private

◆ spill_start_index_

int v8::internal::compiler::LiveRange::spill_start_index_
private

Definition at line 314 of file register-allocator.h.

Referenced by SetSpillStartIndex(), and spill_start_index().

◆ spilled_

bool v8::internal::compiler::LiveRange::spilled_
private

Definition at line 298 of file register-allocator.h.

Referenced by IsSpilled(), and MakeSpilled().


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