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 { |
Jarin
2015/08/04 19:39:43
I am really confused about this. The name refers t
Mircea Trofin
2015/08/04 20:34:46
Sorry - the name was a point in time :) It's not f
|
+ 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); |
}; |