| Index: src/compiler/register-allocator.h
|
| diff --git a/src/compiler/register-allocator.h b/src/compiler/register-allocator.h
|
| index cd3a5f6ca5b1cb7aff1b38ee9e52917f52be2622..90337190c4901521d5d046bae9cebbd5589769c1 100644
|
| --- a/src/compiler/register-allocator.h
|
| +++ b/src/compiler/register-allocator.h
|
| @@ -334,6 +334,9 @@ class LiveRange final : public ZoneObject {
|
| // range and which follows both start and last processed use position
|
| UsePosition* NextRegisterPosition(LifetimePosition start) const;
|
|
|
| + // Returns the first use position requiring stack slot, or nullptr.
|
| + UsePosition* NextSlotPosition(LifetimePosition start) const;
|
| +
|
| // Returns use position for which register is beneficial in this live
|
| // range and which follows both start and last processed use position
|
| UsePosition* NextUsePositionRegisterIsBeneficial(
|
| @@ -401,6 +404,19 @@ class LiveRange final : public ZoneObject {
|
| void CommitSpillsAtDefinition(InstructionSequence* sequence,
|
| const InstructionOperand& operand,
|
| bool might_be_duplicated);
|
| + // This must be applied on top level ranges.
|
| + // If only one of the children(1) of this range is spilled, and the block is
|
| + // deferred(2), then we will spill in that block rather than at definition,
|
| + // to avoid the penalty of the spill operation.
|
| + // (1) if the top level were spilled, it means it is defined on the stack,
|
| + // so we wouldn't have had spilled it at definition in the first place. If
|
| + // more than one child is spilled, we would also need to change how we handle
|
| + // traced references, and we'd need to ensure the first spill dominates the
|
| + // rest.
|
| + // (2) if the block is not deferred, it may be on a hot path (or loop), case
|
| + // in which it may be worse to spill in it.
|
| + bool TryCommitSpillInDeferredBlock(InstructionSequence* code,
|
| + const InstructionOperand& spill_operand);
|
|
|
| void SetSpillStartIndex(int start) {
|
| spill_start_index_ = Min(start, spill_start_index_);
|
| @@ -437,6 +453,10 @@ class LiveRange final : public ZoneObject {
|
| float weight() const { return weight_; }
|
| void set_weight(float weight) { weight_ = weight; }
|
|
|
| + bool IsSpilledInSingleDeferredBlock() const {
|
| + return spilled_in_deferred_block_;
|
| + }
|
| +
|
| static const int kInvalidSize = -1;
|
| static const float kInvalidWeight;
|
| static const float kMaxWeight;
|
| @@ -489,6 +509,10 @@ class LiveRange final : public ZoneObject {
|
| // greedy: a metric for resolving conflicts between ranges with an assigned
|
| // register and ranges that intersect them and need a register.
|
| float weight_;
|
| +
|
| + // TODO(mtrofin): generalize spilling after definition, currently specialized
|
| + // just for spill in a single deferred block.
|
| + bool spilled_in_deferred_block_;
|
| DISALLOW_COPY_AND_ASSIGN(LiveRange);
|
| };
|
|
|
|
|