5#ifndef V8_COMPILER_BACKEND_REGISTER_ALLOCATOR_H_
6#define V8_COMPILER_BACKEND_REGISTER_ALLOCATOR_H_
56 if (pos1 > pos2) std::swap(pos1, pos2);
171 "Code relies on kStep and kHalfStep being a power of two");
179 os <<
'@' <<
pos.ToInstructionIndex();
180 if (
pos.IsGapPosition()) {
195class TopLevelLiveRange;
405 if (intersection_start < intersection_end)
return intersection_start;
432 return std::tie(
start_,
end_) == std::tie(other.start_, other.end_);
437 return start_ < other.start_;
441 os <<
'[' <<
start() <<
", " <<
end() <<
')';
477 return RegisterBeneficialField::decode(
flags_);
480 return SpillDetrimentalField::decode(
flags_);
490 flags_ = AssignedRegisterField::update(
flags_, register_code);
497 return HintTypeField::decode(
flags_);
499 bool HasHint()
const;
500 bool HintRegister(
int* register_code)
const;
504 return hint_type() != UsePositionHintType::kUnresolved;
510 return left->
pos() < right->pos();
551 static_assert(std::is_trivially_destructible<T>::value);
585 return *std::prev(
end());
589 return *std::prev(
end());
605 template <GrowthDirection direction = kFrontOrBack>
609 size_t old_size =
size();
623 std::copy(copy_src_begin, copy_src_end,
data_begin_);
630 std::copy_backward(copy_src_begin, copy_src_end,
data_end_);
634 *insert_position =
value;
644 return insert_position;
655 size_t old_size =
size();
686 DCHECK_EQ(other.storage_begin_, other.data_begin_);
698 size_t merged_size = this->
size() + other.
size();
701 result.data_begin_ -= merged_size;
703 std::copy(other.begin(), other.end(),
result.data_begin_ + this->size());
706 *
this = std::move(
result);
720 template <GrowthDirection direction>
733 template <GrowthDirection direction>
735 size_t new_minimum_capacity) {
738 size_t new_capacity = std::max(
kMinCapacity, new_minimum_capacity);
742 size_t remaining_capacity = new_capacity - old.size();
743 size_t remaining_capacity_front =
757 void Verify()
const {
791 bool IsTopLevel()
const;
797 bool IsEmpty()
const {
return intervals_.empty(); }
802 return RepresentationField::decode(bits_);
809 void set_assigned_register(
int reg);
810 void UnsetAssignedRegister();
816 bits_ = ControlFlowRegisterHint::update(bits_,
reg);
819 return ControlFlowRegisterHint::decode(bits_);
822 int hint = controlflow_hint();
829 bool spilled()
const {
return SpilledField::decode(bits_); }
830 void AttachToNext(
Zone* zone);
871 bool RegisterFromFirstHint(
int* register_index);
874 return positions_span_[current_hint_position_index_];
889 bool ShouldBeAllocatedBefore(
const LiveRange* other)
const;
898 void VerifyChildStructure()
const {
904 void ConvertUsesToOperand(
const InstructionOperand& op,
905 const InstructionOperand& spill_op);
906 void SetUseHints(
int register_index);
911 void Print(
bool with_children)
const;
913 bool RegisterFromBundle(
int* hint)
const;
914 void UpdateBundleRegister(
int reg)
const;
923 void set_spilled(
bool value) { bits_ = SpilledField::update(bits_, value); }
931 void VerifyPositions()
const;
932 void VerifyIntervals()
const;
962 size_t current_hint_position_index_ = 0;
1028 bool is_phi()
const {
return IsPhiField::decode(bits_); }
1029 void set_is_phi(
bool value) { bits_ = IsPhiField::update(bits_, value); }
1034 bits_ = IsNonLoopPhiField::update(bits_, value);
1037 return SpillAtLoopHeaderNotBeneficialField::decode(bits_);
1040 bits_ = SpillAtLoopHeaderNotBeneficialField::update(bits_,
true);
1046 return slot_use_kind() > SlotUseKind::kNoSlotUse;
1050 return slot_use_kind() == SlotUseKind::kGeneralSlotUse;
1054 bits_ = HasSlotUseField::update(bits_, SlotUseKind::kNoSlotUse);
1057 bits_ = HasSlotUseField::update(bits_, std::max(slot_use_kind(), value));
1092 bits_ = SpillTypeField::update(bits_, value);
1096 DCHECK_EQ(SpillType::kSpillOperand, spill_type());
1097 return spill_operand_;
1101 DCHECK_NE(SpillType::kSpillOperand, spill_type());
1102 return spill_range_;
1106 DCHECK_GE(spill_type(), SpillType::kSpillRange);
1107 return spill_range_;
1110 return spill_type() == SpillType::kNoSpillType;
1113 return spill_type() == SpillType::kSpillOperand;
1117 return spill_type() == SpillType::kSpillRange;
1121 void RecordSpillLocation(
Zone* zone,
int gap_index,
1125 spill_start_index_ = std::min(
start, spill_start_index_);
1144 spill_start_index_ = -1;
1145 spilled_in_deferred_blocks_ =
true;
1146 spill_move_insertion_locations_ =
nullptr;
1153 spill_start_index_ = -1;
1154 spill_move_insertion_locations_ =
nullptr;
1162 if (spill_type() == SpillType::kDeferredSpillRange) {
1163 set_spill_type(SpillType::kSpillRange);
1168 return !HasSpillOperand() && spill_range_ ==
nullptr;
1174 void Verify()
const;
1175 void VerifyChildrenInOrder()
const;
1187 return spill_type() == SpillType::kDeferredSpillRange;
1190 struct SpillMoveInsertionList;
1194 DCHECK(!IsSpilledOnlyInDeferredBlocks(data));
1195 return spill_move_insertion_locations_;
1205 DCHECK(spill_type() == SpillType::kSpillRange);
1207 ? SpillRangeMode::kSpillLater
1208 : SpillRangeMode::kSpillAtDefinition;
1210 DCHECK(SpillRangeModeField::decode(bits_) == SpillRangeMode::kNotSet ||
1211 SpillRangeModeField::decode(bits_) == new_mode);
1212 bits_ = SpillRangeModeField::update(bits_, new_mode);
1216 DCHECK_IMPLIES(HasGeneralSpillRange(), SpillRangeModeField::decode(bits_) !=
1217 SpillRangeMode::kNotSet);
1218 return SpillRangeModeField::decode(bits_) == SpillRangeMode::kSpillLater;
1223 DCHECK(IsSpilledOnlyInDeferredBlocks(data));
1224 GetListOfBlocksRequiringSpillOperands(data)->Add(block_id.
ToInt());
1229 DCHECK(IsSpilledOnlyInDeferredBlocks(data));
1230 return list_of_blocks_requiring_spill_operands_;
1354 bool is_tagged,
bool is_input,
1393 void Verify()
const;
1394 bool IntervalStartsAtBlockBoundary(
UseInterval interval)
const;
1395 bool IntervalPredecessorsCoveredByRange(
UseInterval interval,
1397 bool NextIntervalStartsInDifferentBlocks(
UseInterval interval,
1443 return block->IsDeferred() ? SpillMode::kSpillDeferred
1444 : SpillMode::kSpillAtDefinition;
1484 int instruction_index);
1501 return range !=
nullptr && !range->IsEmpty() && range->kind() ==
mode();
1573 return a->ShouldBeAllocatedBefore(b);
1656 int* num_codes,
const int** codes)
const;
1658 const int** codes)
const;
1734class LiveRangeBoundArray;
#define SLOW_DCHECK(condition)
static constexpr int kMaxRegisters
T * AllocateArray(size_t length)
RegisterAllocationData * data_
InstructionSequence * code() const
RegisterAllocationData * data() const
BundleBuilder(RegisterAllocationData *data)
void MeetRegisterConstraintsForLastInstructionInBlock(const InstructionBlock *block)
void MeetRegisterConstraints()
ConstraintBuilder(const ConstraintBuilder &)=delete
ConstraintBuilder & operator=(const ConstraintBuilder &)=delete
Zone * allocation_zone() const
RegisterAllocationData * data() const
void MeetConstraintsBefore(int index)
InstructionOperand * AllocateFixed(UnallocatedOperand *operand, int pos, bool is_tagged, bool is_input, bool is_output)
void MeetConstraintsAfter(int index)
ConstraintBuilder(RegisterAllocationData *data)
RegisterAllocationData *const data_
InstructionSequence * code() const
const_iterator end() const
T & operator[](size_t position)
size_t space_at_front() const
size_t space_at_back() const
V8_NOINLINE V8_PRESERVE_MOST void GrowAt(Zone *zone, size_t new_minimum_capacity)
iterator insert(Zone *zone, const_iterator position, const T &value)
V8_INLINE void EnsureOneMoreCapacityAt(Zone *zone)
ASSERT_TRIVIALLY_COPYABLE(T)
DoubleEndedSplitVector< T > SplitAt(const_iterator split_begin_const)
void Append(Zone *zone, DoubleEndedSplitVector< T > other)
void push_front(Zone *zone, const T &value)
static constexpr size_t kMinCapacity
const T & operator[](size_t position) const
const_iterator begin() const
static LifetimePosition MaxPosition()
static bool ExistsGapPositionBetween(LifetimePosition pos1, LifetimePosition pos2)
LifetimePosition PrevStart() const
bool operator>=(const LifetimePosition &that) const
LifetimePosition FullStart() const
static LifetimePosition InstructionFromInstructionIndex(int index)
static LifetimePosition FromInt(int value)
LifetimePosition NextStart() const
bool operator!=(const LifetimePosition &that) const
bool operator<=(const LifetimePosition &that) const
LifetimePosition NextFullStart() const
LifetimePosition Start() const
int ToInstructionIndex() const
static const int kHalfStep
bool operator<(const LifetimePosition &that) const
static LifetimePosition GapFromInstructionIndex(int index)
bool operator>(const LifetimePosition &that) const
static LifetimePosition Invalid()
LifetimePosition(int value)
bool operator==(const LifetimePosition &that) const
LifetimePosition End() const
bool IsGapPosition() const
bool IsInstructionPosition() const
LinearScanAllocator & operator=(const LinearScanAllocator &)=delete
void AddToActive(LiveRange *range)
ZoneVector< LiveRange * > & active_live_ranges()
void MaybeUndoPreviousSplit(LiveRange *range, Zone *zone)
LinearScanAllocator(const LinearScanAllocator &)=delete
int LastDeferredInstructionIndex(InstructionBlock *start)
void SpillBetweenUntil(LiveRange *range, LifetimePosition start, LifetimePosition until, LifetimePosition end, SpillMode spill_mode)
void SlowDCheckInactiveLiveRangesIsSorted(int reg)
InactiveLiveRangeQueue::iterator InactiveToActive(InactiveLiveRangeQueue::iterator it, LifetimePosition position)
void SpillNotLiveRanges(RangeRegisterSmallMap &to_be_live, LifetimePosition position, SpillMode spill_mode)
UnhandledLiveRangeQueue & unhandled_live_ranges()
bool CheckConflict(MachineRepresentation rep, int reg, const RangeRegisterSmallMap &to_be_live)
bool TryReuseSpillForPhi(TopLevelLiveRange *range)
int PickRegisterThatIsAvailableLongest(LiveRange *current, int hint_reg, base::Vector< const LifetimePosition > free_until_pos)
RpoNumber ChooseOneOfTwoPredecessorStates(InstructionBlock *current_block, LifetimePosition boundary)
void ProcessCurrentRange(LiveRange *current, SpillMode spill_mode)
ZoneVector< LiveRange * > active_live_ranges_
UnhandledLiveRangeQueue unhandled_live_ranges_
ZoneVector< LiveRange * >::iterator ActiveToInactive(ZoneVector< LiveRange * >::iterator it, LifetimePosition position)
void ForwardStateTo(LifetimePosition position)
void SpillAfter(LiveRange *range, LifetimePosition pos, SpillMode spill_mode)
void FindFreeRegistersForRange(LiveRange *range, base::Vector< LifetimePosition > free_until_pos)
void AllocateBlockedReg(LiveRange *range, SpillMode spill_mode)
void UpdateDeferredFixedRanges(SpillMode spill_mode, InstructionBlock *block)
void MaybeSpillPreviousRanges(LiveRange *begin_range, LifetimePosition begin_pos, LiveRange *end_range)
LiveRange * AssignRegisterOnReload(LiveRange *range, int reg)
LifetimePosition next_active_ranges_change_
InactiveLiveRangeQueue::iterator InactiveToHandled(InactiveLiveRangeQueue::iterator it)
void AddToInactive(LiveRange *range)
bool TryAllocatePreferredReg(LiveRange *range, base::Vector< const LifetimePosition > free_until_pos)
void SpillBetween(LiveRange *range, LifetimePosition start, LifetimePosition end, SpillMode spill_mode)
InactiveLiveRangeQueue & inactive_live_ranges(int reg)
void PrintRangeRow(std::ostream &os, const TopLevelLiveRange *toplevel)
LifetimePosition next_inactive_ranges_change_
bool TryAllocateFreeReg(LiveRange *range, base::Vector< const LifetimePosition > free_until_pos)
void GetSIMD128RegisterSet(int *num_regs, int *num_codes, const int **codes) const
void AddToUnhandled(LiveRange *range)
bool ConsiderBlockForControlFlow(InstructionBlock *current_block, RpoNumber predecessor)
ZoneVector< InactiveLiveRangeQueue > inactive_live_ranges_
LinearScanAllocator(RegisterAllocationData *data, RegisterKind kind, Zone *local_zone)
void GetFPRegisterSet(MachineRepresentation rep, int *num_regs, int *num_codes, const int **codes) const
bool BlockIsDeferredOrImmediatePredecessorIsNotDeferred(const InstructionBlock *block)
void SplitAndSpillIntersecting(LiveRange *range, SpillMode spill_mode)
ZoneVector< LiveRange * >::iterator ActiveToHandled(ZoneVector< LiveRange * >::iterator it)
void SetLiveRangeAssignedRegister(LiveRange *range, int reg)
void ReloadLiveRanges(RangeRegisterSmallMap const &to_be_live, LifetimePosition position)
void PrintRangeOverview()
void ComputeStateFromManyPredecessors(InstructionBlock *current_block, RangeRegisterSmallMap &to_be_live)
bool HasNonDeferredPredecessor(InstructionBlock *block)
UsePosition * Use(LifetimePosition block_start, LifetimePosition position, InstructionOperand *operand, void *hint, UsePositionHintType hint_type, SpillMode spill_mode)
static SparseBitVector * ComputeLiveOut(const InstructionBlock *block, RegisterAllocationData *data)
static int FixedLiveRangeID(int index)
void ProcessPhis(const InstructionBlock *block, SparseBitVector *live)
LiveRangeBuilder(const LiveRangeBuilder &)=delete
LiveRangeBuilder & operator=(const LiveRangeBuilder &)=delete
UsePosition * NewUsePosition(LifetimePosition pos)
Zone * allocation_zone() const
RegisterAllocationData * data() const
UsePosition * NewUsePosition(LifetimePosition pos, InstructionOperand *operand, void *hint, UsePositionHintType hint_type)
SpillMode SpillModeForBlock(const InstructionBlock *block) const
InstructionSequence * code() const
void Use(LifetimePosition block_start, LifetimePosition position, InstructionOperand *operand, SpillMode spill_mode)
static constexpr int kNumberOfFixedRangesPerRegister
TopLevelLiveRange * LiveRangeFor(InstructionOperand *operand, SpillMode spill_mode)
RegisterAllocationData::SpillMode SpillMode
TopLevelLiveRange * FixedLiveRangeFor(int index, SpillMode spill_mode)
void ProcessInstructions(const InstructionBlock *block, SparseBitVector *live)
TopLevelLiveRange * FixedFPLiveRangeFor(int index, MachineRepresentation rep, SpillMode spill_mode)
void MapPhiHint(InstructionOperand *operand, UsePosition *use_pos)
ZoneVector< SparseBitVector * > & live_in_sets() const
void ProcessLoopHeader(const InstructionBlock *block, SparseBitVector *live)
UsePosition * Define(LifetimePosition position, InstructionOperand *operand, void *hint, UsePositionHintType hint_type, SpillMode spill_mode)
void Define(LifetimePosition position, InstructionOperand *operand, SpillMode spill_mode)
TopLevelLiveRange * FixedSIMD128LiveRangeFor(int index, SpillMode spill_mode)
int FixedFPLiveRangeID(int index, MachineRepresentation rep)
void AddInitialIntervals(const InstructionBlock *block, SparseBitVector *live_out)
void ResolvePhiHint(InstructionOperand *operand, UsePosition *use_pos)
const RegisterConfiguration * config() const
RegisterAllocationData *const data_
ZoneMap< InstructionOperand *, UsePosition * > phi_hints_
LiveRangeBuilder(RegisterAllocationData *data, Zone *local_zone)
ZoneVector< UseInterval > intervals_
void MergeSpillRangesAndClear()
void AddRange(TopLevelLiveRange *range)
ZoneVector< TopLevelLiveRange * > ranges_
bool TryAddRange(TopLevelLiveRange *range)
static LiveRangeBundle * TryMerge(LiveRangeBundle *lhs, LiveRangeBundle *rhs)
LiveRangeBundle(Zone *zone, int id)
RegisterAllocationData *const data_
bool CanEagerlyResolveControlFlow(const InstructionBlock *block) const
LiveRangeConnector(const LiveRangeConnector &)=delete
RegisterAllocationData * data() const
void ResolveControlFlow(Zone *local_zone)
InstructionSequence * code() const
LiveRangeConnector & operator=(const LiveRangeConnector &)=delete
void ConnectRanges(Zone *local_zone)
LiveRangeConnector(RegisterAllocationData *data)
void CommitSpillsInDeferredBlocks(TopLevelLiveRange *range, Zone *temp_zone)
base::Vector< UsePosition * > positions() const
TopLevelLiveRange * top_level_
UsePosition * current_hint_position() const
base::Vector< UsePosition * > positions_span_
const TopLevelLiveRange * TopLevel() const
LifetimePosition next_start_
void set_controlflow_hint(int reg)
bool RegisterFromControlFlow(int *reg)
void set_spilled(bool value)
void ResetCurrentHintPosition()
TopLevelLiveRange * TopLevel()
LiveRange(const LiveRange &)=delete
bool ShouldRecombine() const
LiveRange & operator=(const LiveRange &)=delete
int assigned_register() const
const UseIntervalVector & intervals() const
MachineRepresentation representation() const
bool HasRegisterAssigned() const
LifetimePosition Start() const
int controlflow_hint() const
UseIntervalVector intervals_
LifetimePosition NextStart() const
LifetimePosition End() const
UseIntervalVector::iterator current_interval_
RegisterAllocationData *const data_
OperandAssigner(const OperandAssigner &)=delete
OperandAssigner(RegisterAllocationData *data)
RegisterAllocationData * data() const
void DecideSpillingMode()
OperandAssigner & operator=(const OperandAssigner &)=delete
ReferenceMapPopulator & operator=(const ReferenceMapPopulator &)=delete
ReferenceMapPopulator(RegisterAllocationData *data)
void PopulateReferenceMaps()
RegisterAllocationData * data() const
bool SafePointsAreInOrder() const
RegisterAllocationData *const data_
ReferenceMapPopulator(const ReferenceMapPopulator &)=delete
PhiMapValue(PhiInstruction *phi, const InstructionBlock *block, Zone *zone)
PhiInstruction *const phi_
int assigned_register() const
ZoneVector< InstructionOperand * > incoming_operands_
void CommitAssignment(const InstructionOperand &operand)
const PhiInstruction * phi() const
const InstructionBlock *const block_
void AddOperand(InstructionOperand *operand)
void set_assigned_register(int register_code)
const InstructionBlock * block() const
void UnsetAssignedRegister()
const ZoneVector< TopLevelLiveRange * > & fixed_simd128_live_ranges() const
const char *const debug_name_
SpillRange * AssignSpillRangeToLiveRange(TopLevelLiveRange *range, SpillMode spill_mode)
const RegisterConfiguration * config() const
BitVector * fixed_fp_register_use_
const char * debug_name() const
ZoneVector< TopLevelLiveRange * > & fixed_double_live_ranges()
RegisterAllocationData(const RegisterAllocationData &)=delete
ZoneVector< TopLevelLiveRange * > live_ranges_
TopLevelLiveRange * GetLiveRangeFor(int index)
const ZoneVector< TopLevelLiveRange * > & fixed_live_ranges() const
ZoneVector< SparseBitVector * > & live_out_sets()
SpillRange * CreateSpillRangeForLiveRange(TopLevelLiveRange *range)
ZoneVector< SparseBitVector * > & live_in_sets()
ZoneVector< TopLevelLiveRange * > & fixed_float_live_ranges()
void RememberSpillState(RpoNumber block, const ZoneVector< LiveRange * > &state)
ZoneMap< TopLevelLiveRange *, AllocatedOperand * > slot_for_const_range_
DelayedReferences & delayed_references()
ZoneVector< TopLevelLiveRange * > & live_ranges()
RangesWithPreassignedSlots & preassigned_slot_ranges()
ZoneMap< TopLevelLiveRange *, AllocatedOperand * > & slot_for_const_range()
BitVector * fixed_register_use_
const ZoneVector< TopLevelLiveRange * > & fixed_double_live_ranges() const
ZoneVector< ZoneVector< LiveRange * > > spill_state_
ZoneVector< LiveRange * > & GetSpillState(RpoNumber block)
BitVector * assigned_registers_
MoveOperands * AddGapMove(int index, Instruction::GapPosition position, const InstructionOperand &from, const InstructionOperand &to)
ZoneVector< TopLevelLiveRange * > fixed_double_live_ranges_
ZoneVector< TopLevelLiveRange * > & fixed_live_ranges()
const RegisterConfiguration *const config_
ZoneVector< TopLevelLiveRange * > fixed_float_live_ranges_
bool HasFixedUse(MachineRepresentation rep, int index)
bool IsBlockBoundary(LifetimePosition pos) const
TickCounter * tick_counter()
const ZoneVector< TopLevelLiveRange * > & live_ranges() const
ZoneVector< SparseBitVector * > live_in_sets_
Zone *const allocation_zone_
RegisterAllocationData & operator=(const RegisterAllocationData &)=delete
void MarkFixedUse(MachineRepresentation rep, int index)
PhiMapValue * GetPhiMapValueFor(TopLevelLiveRange *top_range)
InstructionSequence *const code_
TopLevelLiveRange * NewLiveRange(int index, MachineRepresentation rep)
MachineRepresentation RepresentationFor(int virtual_register)
PhiMapValue * InitializePhiMap(const InstructionBlock *block, PhiInstruction *phi)
const ZoneVector< TopLevelLiveRange * > & fixed_float_live_ranges() const
BitVector * fixed_simd128_register_use_
ZoneVector< TopLevelLiveRange * > fixed_live_ranges_
int virtual_register_count_
void MarkAllocated(MachineRepresentation rep, int index)
BitVector * assigned_double_registers_
static constexpr int kNumberOfFixedRangesPerRegister
BitVector * assigned_simd128_registers_
RangesWithPreassignedSlots preassigned_slot_ranges_
ZoneVector< TopLevelLiveRange * > fixed_simd128_live_ranges_
Zone * allocation_zone() const
ZoneVector< TopLevelLiveRange * > & fixed_simd128_live_ranges()
bool ExistsUseWithoutDefinition()
DelayedReferences delayed_references_
ZoneVector< SparseBitVector * > live_out_sets_
bool RangesDefinedInDeferredStayInDeferred()
TickCounter *const tick_counter_
InstructionSequence * code() const
LifetimePosition FindOptimalSpillingPos(LiveRange *range, LifetimePosition pos, SpillMode spill_mode, LiveRange **begin_spill_out)
RegisterAllocationData * data() const
void Spill(LiveRange *range, SpillMode spill_mode)
const int * allocatable_register_codes_
bool CanProcessRange(LiveRange *range) const
LiveRange * SplitBetween(LiveRange *range, LifetimePosition start, LifetimePosition end)
RegisterAllocationData::SpillMode SpillMode
const char * RegisterName(int allocation_index) const
RegisterAllocator(RegisterAllocationData *data, RegisterKind kind)
LifetimePosition GetSplitPositionForInstruction(const LiveRange *range, int instruction_index)
const int * allocatable_register_codes() const
RegisterAllocator(const RegisterAllocator &)=delete
int num_registers() const
LifetimePosition FindOptimalSplitPos(LifetimePosition start, LifetimePosition end)
RegisterAllocator & operator=(const RegisterAllocator &)=delete
InstructionSequence * code() const
void SplitAndSpillRangesDefinedByMemoryOperand()
int num_allocatable_registers_
const ZoneVector< TopLevelLiveRange * > & GetFixedRegisters() const
RegisterKind mode() const
bool check_fp_aliasing() const
LiveRange * SplitRangeAt(LiveRange *range, LifetimePosition pos)
RegisterAllocationData *const data_
int num_allocatable_registers() const
Zone * allocation_zone() const
bool TryMerge(SpillRange *other)
void set_assigned_slot(int index)
SpillRange(const SpillRange &)=delete
int assigned_slot() const
SpillRange(TopLevelLiveRange *range, Zone *zone)
static const int kUnassignedSlot
ZoneVector< UseInterval > intervals_
SpillRange & operator=(const SpillRange &)=delete
ZoneVector< TopLevelLiveRange * > ranges_
SlotUseKind slot_use_kind() const
bool IsSpilledOnlyInDeferredBlocks(const RegisterAllocationData *data) const
void set_deferred_fixed()
bool HasNoSpillType() const
bool has_preassigned_slot() const
bool has_slot_use() const
void set_spilling_at_loop_header_not_beneficial()
bool has_preassigned_slot_
bool HasSpillRange() const
void set_is_non_loop_phi(bool value)
void TransitionRangeToDeferredSpill(Zone *zone)
void set_is_phi(bool value)
void UpdateSpillRangePostMerge(TopLevelLiveRange *merged)
void set_bundle(LiveRangeBundle *bundle)
void TransitionRangeToSpillAtDefinition()
void register_slot_use(SlotUseKind value)
void AddBlockRequiringSpillOperand(RpoNumber block_id, const RegisterAllocationData *data)
TopLevelLiveRange(const TopLevelLiveRange &)=delete
SparseBitVector * list_of_blocks_requiring_spill_operands_
LiveRangeBundle * get_bundle() const
bool HasSpillOperand() const
bool SpillAtLoopHeaderNotBeneficial() const
SpillMoveInsertionList * GetSpillMoveInsertionLocations(const RegisterAllocationData *data) const
SpillRange * spill_range_
const ZoneVector< LiveRange * > & Children() const
bool HasGeneralSpillRange() const
bool IsDeferredFixed() const
ZoneVector< LiveRange * > children_
bool spilled_in_deferred_blocks_
UsePositionVector positions_
InstructionOperand * GetSpillOperand() const
SparseBitVector * GetListOfBlocksRequiringSpillOperands(const RegisterAllocationData *data) const
bool LateSpillingSelected() const
SpillMoveInsertionList * spill_move_insertion_locations_
bool has_non_deferred_slot_use() const
void SetSpillStartIndex(int start)
bool is_non_loop_phi() const
void SetLateSpillingSelected(bool late_spilling_selected)
InstructionOperand * spill_operand_
int spill_start_index() const
void MarkHasPreassignedSlot()
bool MayRequireSpillRange() const
TopLevelLiveRange & operator=(const TopLevelLiveRange &)=delete
SpillRange * GetSpillRange() const
void TreatAsSpilledInDeferredBlock(Zone *zone)
SpillRange * GetAllocatedSpillRange() const
void set_spill_type(SpillType value)
SpillType spill_type() const
LifetimePosition start() const
bool operator!=(const UseInterval &other) const
LifetimePosition Intersect(const UseInterval &other) const
UseInterval(LifetimePosition start, LifetimePosition end)
void set_start(LifetimePosition start)
bool operator==(const UseInterval &other) const
int FirstGapIndex() const
UseInterval SplitAt(LifetimePosition pos)
void PrettyPrint(std::ostream &os) const
LifetimePosition end() const
bool operator<(const UseInterval &other) const
bool Contains(LifetimePosition point) const
void set_end(LifetimePosition end)
InstructionOperand * operand() const
UsePosition & operator=(const UsePosition &)=delete
bool RegisterIsBeneficial() const
bool SpillDetrimental() const
UsePositionHintType hint_type() const
void set_assigned_register(int register_code)
UsePosition(const UsePosition &)=delete
InstructionOperand *const operand_
LifetimePosition pos() const
LifetimePosition const pos_
void set_spill_detrimental()
UsePositionType type() const
const v8::base::TimeTicks end_
ArrayReduceDirection direction
ZoneVector< RpoNumber > & result
LiftoffAssembler::CacheState state
constexpr bool IsPowerOfTwo(T value)
static const int32_t kUnassignedRegister
@ kRegisterOrSlotOrConstant
std::ostream & operator<<(std::ostream &os, AccessMode access_mode)
Node::Uses::const_iterator begin(const Node::Uses &uses)
ZoneUnorderedMap< int, BytecodeSequenceNode * > children_
#define NON_EXPORTED_BASE(code)
#define DCHECK_LE(v1, v2)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define V8_EXPORT_PRIVATE
bool operator()(const LiveRange *a, const LiveRange *b) const
bool operator()(const LiveRange *a, const LiveRange *b) const
bool operator()(const LiveRange *left, const LiveRange *right) const
const RegisterConfiguration * register_configuration_
InstructionOperand * operand
bool operator()(const UsePosition *left, const UsePosition *right) const
#define V8_LIKELY(condition)