| Index: src/lithium-allocator.h
|
| diff --git a/src/lithium-allocator.h b/src/lithium-allocator.h
|
| index 5b05263575dcc45d2d1f9e53ee8066054660d49f..6259a195b46441c06677066dacc09482658ea7e3 100644
|
| --- a/src/lithium-allocator.h
|
| +++ b/src/lithium-allocator.h
|
| @@ -290,7 +290,10 @@ class LiveRange: public ZoneObject {
|
| bool IsEmpty() const { return first_interval() == NULL; }
|
| LOperand* CreateAssignedOperand(Zone* zone);
|
| int assigned_register() const { return assigned_register_; }
|
| +
|
| int spill_start_index() const { return spill_start_index_; }
|
| + void set_spill_start_index(int start) { spill_start_index_ = start; }
|
| +
|
| void set_assigned_register(int reg,
|
| RegisterKind register_kind,
|
| Zone* zone);
|
| @@ -347,10 +350,6 @@ class LiveRange: public ZoneObject {
|
| LOperand* GetSpillOperand() const { return spill_operand_; }
|
| void SetSpillOperand(LOperand* operand);
|
|
|
| - void SetSpillStartIndex(int start) {
|
| - spill_start_index_ = Min(start, spill_start_index_);
|
| - }
|
| -
|
| bool ShouldBeAllocatedBefore(const LiveRange* other) const;
|
| bool CanCover(LifetimePosition position) const;
|
| bool Covers(LifetimePosition position);
|
| @@ -376,6 +375,24 @@ class LiveRange: public ZoneObject {
|
| void Verify() const;
|
| #endif
|
|
|
| + static const intptr_t kDisabledSpillStoreSinkingMarker = -1;
|
| +
|
| + LOperand* spill_source() { return spill_source_; }
|
| + void set_spill_source(LOperand* spill_source) {
|
| + spill_source_ = spill_source;
|
| + }
|
| +
|
| + bool HasPendingSpillStore() {
|
| + return (spill_source() !=
|
| + reinterpret_cast<LOperand*>(kDisabledSpillStoreSinkingMarker)) &&
|
| + (spill_source() != NULL);
|
| + }
|
| +
|
| + void DisableSpillStoreSinking() {
|
| + set_spill_source(
|
| + reinterpret_cast<LOperand*>(kDisabledSpillStoreSinkingMarker));
|
| + }
|
| +
|
| private:
|
| void ConvertOperands(Zone* zone);
|
| UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
|
| @@ -396,6 +413,7 @@ class LiveRange: public ZoneObject {
|
| UsePosition* last_processed_use_;
|
| LOperand* spill_operand_;
|
| int spill_start_index_;
|
| + LOperand* spill_source_;
|
| };
|
|
|
|
|
| @@ -564,6 +582,17 @@ class LAllocator BASE_EMBEDDED {
|
| void SplitAndSpillIntersecting(LiveRange* range);
|
|
|
| void Spill(LiveRange* range);
|
| +
|
| + // Emit spill store for the given range that moves value from the register
|
| + // where it was produced (spill source) to the allocated spill slot.
|
| + void EmitSpillStore(LiveRange* range);
|
| + void EmitSpillStore(int pos, LOperand* source, LOperand* spill);
|
| +
|
| + // Try sink spill store for the given range down to the beginning of the
|
| + // given block. This is done only if the block dominates all spilled split
|
| + // siblings.
|
| + bool TrySinkSpillStoreTo(LiveRange* range, HBasicBlock* block);
|
| +
|
| bool IsBlockBoundary(LifetimePosition pos);
|
|
|
| // Helper methods for resolving control flow.
|
| @@ -571,6 +600,10 @@ class LAllocator BASE_EMBEDDED {
|
| HBasicBlock* block,
|
| HBasicBlock* pred);
|
|
|
| + // Emit all pending spill stores for ranges that have spilled siblings sinking
|
| + // stores down to loop exits whenever possible.
|
| + void SinkSpillStores();
|
| +
|
| // Return parallel move that should be used to connect ranges split at the
|
| // given position.
|
| LParallelMove* GetConnectingParallelMove(LifetimePosition pos);
|
| @@ -617,6 +650,10 @@ class LAllocator BASE_EMBEDDED {
|
| ZoneList<LiveRange*> inactive_live_ranges_;
|
| ZoneList<LiveRange*> reusable_slots_;
|
|
|
| + // List of live ranges that were spilled but did not have
|
| + // spill store emitted eagerly.
|
| + ZoneList<LiveRange*> pending_spilled_;
|
| +
|
| // Next virtual register number to be assigned to temporaries.
|
| int next_virtual_register_;
|
| int first_artificial_register_;
|
|
|