| Index: src/compiler/register-allocator.h
|
| diff --git a/src/compiler/register-allocator.h b/src/compiler/register-allocator.h
|
| index 2e63d36e122dd11a8f5d4b9a869aef19b149a3cf..c537bbe7f93352720d659b87dc449843c16b3b27 100644
|
| --- a/src/compiler/register-allocator.h
|
| +++ b/src/compiler/register-allocator.h
|
| @@ -273,7 +273,7 @@ class UsePosition final : public ZoneObject {
|
|
|
|
|
| class SpillRange;
|
| -
|
| +class RegisterAllocationData;
|
|
|
| // Representation of SSA values' live ranges as a collection of (continuous)
|
| // intervals over the instruction ordering.
|
| @@ -355,6 +355,9 @@ class LiveRange final : public ZoneObject {
|
| // All uses following the given position will be moved from this
|
| // live range to the result live range.
|
| void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone);
|
| + void Splinter(LifetimePosition start, LifetimePosition end, LiveRange* result,
|
| + Zone* zone);
|
| + void Merge(LiveRange* other, RegisterAllocationData* data);
|
|
|
| // Returns nullptr when no register is hinted, otherwise sets register_index.
|
| UsePosition* FirstHintPosition(int* register_index) const;
|
| @@ -384,6 +387,12 @@ class LiveRange final : public ZoneObject {
|
| DCHECK(spill_type() == SpillType::kSpillOperand);
|
| return spill_operand_;
|
| }
|
| +
|
| + SpillRange* GetAllocatedSpillRange() const {
|
| + DCHECK(spill_type() != SpillType::kSpillOperand);
|
| + return spill_range_;
|
| + }
|
| +
|
| SpillRange* GetSpillRange() const {
|
| DCHECK(spill_type() == SpillType::kSpillRange);
|
| return spill_range_;
|
| @@ -395,6 +404,11 @@ class LiveRange final : public ZoneObject {
|
| return spill_type() == SpillType::kSpillOperand;
|
| }
|
| bool HasSpillRange() const { return spill_type() == SpillType::kSpillRange; }
|
| + bool MayRequireSpillRange() const {
|
| + DCHECK(!IsChild() && !IsSplinter());
|
| + return !HasSpillOperand() && spill_range_ == nullptr;
|
| + }
|
| +
|
| AllocatedOperand GetSpillRangeOperand() const;
|
|
|
| void SpillAtDefinition(Zone* zone, int gap_index,
|
| @@ -458,17 +472,35 @@ class LiveRange final : public ZoneObject {
|
| static const float kInvalidWeight;
|
| static const float kMaxWeight;
|
|
|
| - private:
|
| + LiveRange* splintered_from() const {
|
| + DCHECK(!IsChild());
|
| + return splintered_from_;
|
| + }
|
| + bool IsSplinter() const {
|
| + DCHECK(!IsChild());
|
| + return splintered_from_ != nullptr;
|
| + }
|
| +
|
| void set_spill_type(SpillType value) {
|
| bits_ = SpillTypeField::update(bits_, value);
|
| }
|
|
|
| + private:
|
| + void AppendChild(LiveRange* other);
|
| + void UpdateParentForAllChildren(LiveRange* new_parent);
|
| + void UpdateSpillRangePostMerge(LiveRange* merged);
|
| +
|
| + void SetSplinteredFrom(LiveRange* splinter_parent);
|
| +
|
| +
|
| 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;
|
|
|
| + LiveRange* GetLastChild();
|
| +
|
| typedef BitField<bool, 0, 1> SpilledField;
|
| typedef BitField<bool, 1, 1> HasSlotUseField;
|
| typedef BitField<bool, 2, 1> IsPhiField;
|
| @@ -485,6 +517,7 @@ class LiveRange final : public ZoneObject {
|
| UsePosition* first_pos_;
|
| LiveRange* parent_;
|
| LiveRange* next_;
|
| + LiveRange* splintered_from_;
|
| union {
|
| // Correct value determined by spill_type()
|
| InstructionOperand* spill_operand_;
|
| @@ -543,10 +576,13 @@ class SpillRange final : public ZoneObject {
|
| DCHECK_NE(kUnassignedSlot, assigned_slot_);
|
| return assigned_slot_;
|
| }
|
| + const ZoneVector<LiveRange*>& live_ranges() const { return live_ranges_; }
|
| + ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; }
|
| + int byte_width() const { return byte_width_; }
|
| + RegisterKind kind() const { return kind_; }
|
|
|
| private:
|
| LifetimePosition End() const { return end_position_; }
|
| - ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; }
|
| bool IsIntersectingWith(SpillRange* other) const;
|
| // Merge intervals, making sure the use intervals are sorted
|
| void MergeDisjointIntervals(UseInterval* other);
|
| @@ -555,6 +591,8 @@ class SpillRange final : public ZoneObject {
|
| UseInterval* use_interval_;
|
| LifetimePosition end_position_;
|
| int assigned_slot_;
|
| + int byte_width_;
|
| + RegisterKind kind_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(SpillRange);
|
| };
|
| @@ -612,7 +650,7 @@ class RegisterAllocationData final : public ZoneObject {
|
| return fixed_double_live_ranges_;
|
| }
|
| ZoneVector<BitVector*>& live_in_sets() { return live_in_sets_; }
|
| - ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; }
|
| + ZoneSet<SpillRange*>& spill_ranges() { return spill_ranges_; }
|
| DelayedReferences& delayed_references() { return delayed_references_; }
|
| InstructionSequence* code() const { return code_; }
|
| // This zone is for datastructures only needed during register allocation
|
| @@ -630,9 +668,11 @@ class RegisterAllocationData final : public ZoneObject {
|
| LiveRange* LiveRangeFor(int index);
|
| // Creates a new live range.
|
| LiveRange* NewLiveRange(int index, MachineType machine_type);
|
| + LiveRange* NextLiveRange(MachineType machine_type);
|
| LiveRange* NewChildRangeFor(LiveRange* range);
|
|
|
| SpillRange* AssignSpillRangeToLiveRange(LiveRange* range);
|
| + SpillRange* CreateSpillRangeForLiveRange(LiveRange* range);
|
|
|
| MoveOperands* AddGapMove(int index, Instruction::GapPosition position,
|
| const InstructionOperand& from,
|
| @@ -656,6 +696,7 @@ class RegisterAllocationData final : public ZoneObject {
|
| void Print(const LiveRange* range, bool with_children = false);
|
| void Print(const InstructionOperand& op);
|
| void Print(const MoveOperands* move);
|
| + void Print(const SpillRange* spill_range);
|
|
|
| private:
|
| Zone* const allocation_zone_;
|
| @@ -668,7 +709,7 @@ class RegisterAllocationData final : public ZoneObject {
|
| ZoneVector<LiveRange*> live_ranges_;
|
| ZoneVector<LiveRange*> fixed_live_ranges_;
|
| ZoneVector<LiveRange*> fixed_double_live_ranges_;
|
| - ZoneVector<SpillRange*> spill_ranges_;
|
| + ZoneSet<SpillRange*> spill_ranges_;
|
| DelayedReferences delayed_references_;
|
| BitVector* assigned_registers_;
|
| BitVector* assigned_double_registers_;
|
| @@ -721,6 +762,8 @@ class LiveRangeBuilder final : public ZoneObject {
|
|
|
| // Phase 3: compute liveness of all virtual register.
|
| void BuildLiveRanges();
|
| + static BitVector* ComputeLiveOut(const InstructionBlock* block,
|
| + RegisterAllocationData* data);
|
|
|
| private:
|
| RegisterAllocationData* data() const { return data_; }
|
| @@ -737,7 +780,6 @@ class LiveRangeBuilder final : public ZoneObject {
|
| void Verify() const;
|
|
|
| // Liveness analysis support.
|
| - BitVector* ComputeLiveOut(const InstructionBlock* block);
|
| void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out);
|
| void ProcessInstructions(const InstructionBlock* block, BitVector* live);
|
| void ProcessPhis(const InstructionBlock* block, BitVector* live);
|
|
|