| Index: src/compiler/register-allocator.h
|
| diff --git a/src/compiler/register-allocator.h b/src/compiler/register-allocator.h
|
| index ce722325c6ba48e356db28d4894bdc3ae15e215f..50b89ede055b78db461794d25578b67625ba5685 100644
|
| --- a/src/compiler/register-allocator.h
|
| +++ b/src/compiler/register-allocator.h
|
| @@ -60,8 +60,8 @@ class LifetimePosition final {
|
| // Returns true if this lifetime position corresponds to a gap START value
|
| bool IsFullStart() const { return (value_ & (kStep - 1)) == 0; }
|
|
|
| - bool IsGapPosition() { return (value_ & 0x2) == 0; }
|
| - bool IsInstructionPosition() { return !IsGapPosition(); }
|
| + bool IsGapPosition() const { return (value_ & 0x2) == 0; }
|
| + bool IsInstructionPosition() const { return !IsGapPosition(); }
|
|
|
| // Returns the lifetime position for the current START.
|
| LifetimePosition Start() const {
|
| @@ -287,19 +287,38 @@ class LiveRange final : public ZoneObject {
|
| bool IsFixed() const { return id_ < 0; }
|
| bool IsEmpty() const { return first_interval() == nullptr; }
|
| InstructionOperand GetAssignedOperand() const;
|
| - int assigned_register() const { return assigned_register_; }
|
| int spill_start_index() const { return spill_start_index_; }
|
| +
|
| + int assigned_register() const { return AssignedRegisterField::decode(bits_); }
|
| + bool HasRegisterAssigned() const {
|
| + return assigned_register() != kUnassignedRegister;
|
| + }
|
| void set_assigned_register(int reg);
|
| void UnsetAssignedRegister();
|
| - void MakeSpilled();
|
| - bool is_phi() const { return is_phi_; }
|
| - void set_is_phi(bool is_phi) { is_phi_ = is_phi; }
|
| - bool is_non_loop_phi() const { return is_non_loop_phi_; }
|
| - void set_is_non_loop_phi(bool is_non_loop_phi) {
|
| - is_non_loop_phi_ = is_non_loop_phi;
|
| +
|
| + bool spilled() const { return SpilledField::decode(bits_); }
|
| + void Spill();
|
| +
|
| + RegisterKind kind() const { return RegisterKindField::decode(bits_); }
|
| + void set_kind(RegisterKind kind) {
|
| + bits_ = RegisterKindField::update(bits_, kind);
|
| + }
|
| +
|
| + // Correct only for parent.
|
| + bool is_phi() const { return IsPhiField::decode(bits_); }
|
| + void set_is_phi(bool value) { bits_ = IsPhiField::update(bits_, value); }
|
| +
|
| + // Correct only for parent.
|
| + bool is_non_loop_phi() const { return IsNonLoopPhiField::decode(bits_); }
|
| + void set_is_non_loop_phi(bool value) {
|
| + bits_ = IsNonLoopPhiField::update(bits_, value);
|
| + }
|
| +
|
| + // Relevant only for parent.
|
| + bool has_slot_use() const { return HasSlotUseField::decode(bits_); }
|
| + void set_has_slot_use(bool value) {
|
| + bits_ = HasSlotUseField::update(bits_, value);
|
| }
|
| - bool has_slot_use() const { return has_slot_use_; }
|
| - void set_has_slot_use(bool has_slot_use) { has_slot_use_ = has_slot_use; }
|
|
|
| // Returns use position in this live range that follows both start
|
| // and last processed use position.
|
| @@ -328,12 +347,6 @@ class LiveRange final : public ZoneObject {
|
| // live range to the result live range.
|
| void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone);
|
|
|
| - RegisterKind Kind() const { return kind_; }
|
| - bool HasRegisterAssigned() const {
|
| - return assigned_register_ != kUnassignedRegister;
|
| - }
|
| - bool IsSpilled() const { return spilled_; }
|
| -
|
| // Returns nullptr when no register is hinted, otherwise sets register_index.
|
| UsePosition* FirstHintPosition(int* register_index) const;
|
| UsePosition* FirstHintPosition() const {
|
| @@ -357,20 +370,22 @@ class LiveRange final : public ZoneObject {
|
| }
|
|
|
| enum class SpillType { kNoSpillType, kSpillOperand, kSpillRange };
|
| - SpillType spill_type() const { return spill_type_; }
|
| + SpillType spill_type() const { return SpillTypeField::decode(bits_); }
|
| InstructionOperand* GetSpillOperand() const {
|
| - DCHECK(spill_type_ == SpillType::kSpillOperand);
|
| + DCHECK(spill_type() == SpillType::kSpillOperand);
|
| return spill_operand_;
|
| }
|
| SpillRange* GetSpillRange() const {
|
| - DCHECK(spill_type_ == SpillType::kSpillRange);
|
| + DCHECK(spill_type() == SpillType::kSpillRange);
|
| return spill_range_;
|
| }
|
| - bool HasNoSpillType() const { return spill_type_ == SpillType::kNoSpillType; }
|
| + bool HasNoSpillType() const {
|
| + return spill_type() == SpillType::kNoSpillType;
|
| + }
|
| bool HasSpillOperand() const {
|
| - return spill_type_ == SpillType::kSpillOperand;
|
| + return spill_type() == SpillType::kSpillOperand;
|
| }
|
| - bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; }
|
| + bool HasSpillRange() const { return spill_type() == SpillType::kSpillRange; }
|
|
|
| void SpillAtDefinition(Zone* zone, int gap_index,
|
| InstructionOperand* operand);
|
| @@ -405,41 +420,47 @@ class LiveRange final : public ZoneObject {
|
| void SetUseHints(int register_index);
|
| void UnsetUseHints() { SetUseHints(kUnassignedRegister); }
|
|
|
| - void set_kind(RegisterKind kind) { kind_ = kind; }
|
| -
|
| private:
|
| struct SpillAtDefinitionList;
|
|
|
| + void set_spill_type(SpillType value) {
|
| + bits_ = SpillTypeField::update(bits_, value);
|
| + }
|
| +
|
| + void set_spilled(bool value) { bits_ = SpilledField::update(bits_, value); }
|
| +
|
| UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
|
| void AdvanceLastProcessedMarker(UseInterval* to_start_of,
|
| LifetimePosition but_not_past) const;
|
|
|
| - // TODO(dcarney): pack this structure better.
|
| + typedef BitField<bool, 0, 1> SpilledField;
|
| + typedef BitField<bool, 1, 1> HasSlotUseField;
|
| + typedef BitField<bool, 2, 1> IsPhiField;
|
| + typedef BitField<bool, 3, 1> IsNonLoopPhiField;
|
| + typedef BitField<RegisterKind, 4, 2> RegisterKindField;
|
| + typedef BitField<SpillType, 6, 2> SpillTypeField;
|
| + typedef BitField<int32_t, 8, 6> AssignedRegisterField;
|
| +
|
| int id_;
|
| - bool spilled_ : 1;
|
| - bool has_slot_use_ : 1; // Relevant only for parent.
|
| - bool is_phi_ : 1; // Correct only for parent.
|
| - bool is_non_loop_phi_ : 1; // Correct only for parent.
|
| - RegisterKind kind_;
|
| - int assigned_register_;
|
| + int spill_start_index_;
|
| + uint32_t bits_;
|
| UseInterval* last_interval_;
|
| UseInterval* first_interval_;
|
| UsePosition* first_pos_;
|
| LiveRange* parent_;
|
| LiveRange* next_;
|
| + union {
|
| + // Correct value determined by spill_type()
|
| + InstructionOperand* spill_operand_;
|
| + SpillRange* spill_range_;
|
| + };
|
| + SpillAtDefinitionList* spills_at_definition_;
|
| // This is used as a cache, it doesn't affect correctness.
|
| mutable UseInterval* current_interval_;
|
| // This is used as a cache, it doesn't affect correctness.
|
| mutable UsePosition* last_processed_use_;
|
| // This is used as a cache, it's invalid outside of BuildLiveRanges.
|
| mutable UsePosition* current_hint_position_;
|
| - int spill_start_index_;
|
| - SpillType spill_type_;
|
| - union {
|
| - InstructionOperand* spill_operand_;
|
| - SpillRange* spill_range_;
|
| - };
|
| - SpillAtDefinitionList* spills_at_definition_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(LiveRange);
|
| };
|
| @@ -450,7 +471,7 @@ class SpillRange final : public ZoneObject {
|
| SpillRange(LiveRange* range, Zone* zone);
|
|
|
| UseInterval* interval() const { return use_interval_; }
|
| - RegisterKind Kind() const { return live_ranges_[0]->Kind(); }
|
| + RegisterKind kind() const { return live_ranges_[0]->kind(); }
|
| bool IsEmpty() const { return live_ranges_.empty(); }
|
| bool TryMerge(SpillRange* other);
|
| void SetOperand(AllocatedOperand* op);
|
|
|