1be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Redistribution and use in source and binary forms, with or without
3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// modification, are permitted provided that the following conditions are
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// met:
5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Redistributions of source code must retain the above copyright
7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       notice, this list of conditions and the following disclaimer.
8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Redistributions in binary form must reproduce the above
9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       copyright notice, this list of conditions and the following
10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       disclaimer in the documentation and/or other materials provided
11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       with the distribution.
12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Neither the name of Google Inc. nor the names of its
13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       contributors may be used to endorse or promote products derived
14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       from this software without specific prior written permission.
15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifndef V8_LITHIUM_ALLOCATOR_H_
29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define V8_LITHIUM_ALLOCATOR_H_
30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "v8.h"
32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
331c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org#include "allocation.h"
3483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org#include "lithium.h"
35a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "zone.h"
36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 {
38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal {
39a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Forward declarations.
41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HBasicBlock;
42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HGraph;
43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HInstruction;
44a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HPhi;
45a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HTracer;
46a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HValue;
47a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass BitVector;
48a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass StringStream;
49a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
50a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LArgument;
5128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgclass LPlatformChunk;
520a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgclass LOperand;
530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgclass LUnallocated;
54a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LConstantOperand;
55a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LGap;
56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LParallelMove;
57a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LPointerMap;
58a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LStackSlot;
59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LRegister;
60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
62a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// This class represents a single point of a LOperand's lifetime.
63a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// For each lithium instruction there are exactly two lifetime positions:
64a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// the beginning and the end of the instruction. Lifetime positions for
65a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// different lithium instructions are disjoint.
66a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LifetimePosition {
67a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Return the lifetime position that corresponds to the beginning of
69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // the instruction with the given index.
70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static LifetimePosition FromInstructionIndex(int index) {
71a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return LifetimePosition(index * kStep);
72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
73a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
74a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns a numeric representation of this lifetime position.
75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int Value() const {
76a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return value_;
77a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
78a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
79a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns the index of the instruction to which this lifetime position
80a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // corresponds.
81a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int InstructionIndex() const {
82a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(IsValid());
83a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return value_ / kStep;
84a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
85a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
86a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns true if this lifetime position corresponds to the instruction
87a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // start.
88a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsInstructionStart() const {
89a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return (value_ & (kStep - 1)) == 0;
90a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
91a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
92a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns the lifetime position for the start of the instruction which
93a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // corresponds to this lifetime position.
94a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition InstructionStart() const {
95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(IsValid());
96a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return LifetimePosition(value_ & ~(kStep - 1));
97a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
98a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
99a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns the lifetime position for the end of the instruction which
100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // corresponds to this lifetime position.
101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition InstructionEnd() const {
102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(IsValid());
103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return LifetimePosition(InstructionStart().Value() + kStep/2);
104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns the lifetime position for the beginning of the next instruction.
107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition NextInstruction() const {
108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(IsValid());
109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return LifetimePosition(InstructionStart().Value() + kStep);
110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns the lifetime position for the beginning of the previous
113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // instruction.
114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition PrevInstruction() const {
115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(IsValid());
116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(value_ > 1);
117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return LifetimePosition(InstructionStart().Value() - kStep);
118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Constructs the lifetime position which does not correspond to any
121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // instruction.
122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition() : value_(-1) {}
123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns true if this lifetime positions corrensponds to some
125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // instruction.
126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsValid() const { return value_ != -1; }
127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1285f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static inline LifetimePosition Invalid() { return LifetimePosition(); }
1295f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
1305f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static inline LifetimePosition MaxPosition() {
1315f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // We have to use this kind of getter instead of static member due to
1325f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // crash bug in GDB.
1335f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    return LifetimePosition(kMaxInt);
1345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const int kStep = 2;
138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Code relies on kStep being a power of two.
140a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  STATIC_ASSERT(IS_POWER_OF_TWO(kStep));
141a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
142a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  explicit LifetimePosition(int value) : value_(value) { }
143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int value_;
145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgenum RegisterKind {
1495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  GENERAL_REGISTERS,
1505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  DOUBLE_REGISTERS
1515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org};
1525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
1535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
154a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// A register-allocator view of a Lithium instruction. It contains the id of
155a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// the output operand and a list of input operand uses.
15683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
15783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgclass LInstruction;
15883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgclass LEnvironment;
15983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
16083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Iterator for non-null temp operands.
16183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgclass TempIterator BASE_EMBEDDED {
162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
16383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  inline explicit TempIterator(LInstruction* instr);
164e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  inline bool Done();
165e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  inline LOperand* Current();
16683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  inline void Advance();
167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
16883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org private:
169e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  inline void SkipUninteresting();
17083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  LInstruction* instr_;
17183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  int limit_;
17283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  int current_;
17383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org};
174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
17683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Iterator for non-constant input operands.
17783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgclass InputIterator BASE_EMBEDDED {
17883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org public:
17983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  inline explicit InputIterator(LInstruction* instr);
180e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  inline bool Done();
181e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  inline LOperand* Current();
18283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  inline void Advance();
18383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
18483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org private:
185e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  inline void SkipUninteresting();
18683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  LInstruction* instr_;
18783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  int limit_;
18883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  int current_;
18983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org};
19083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
19283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgclass UseIterator BASE_EMBEDDED {
19383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org public:
19483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  inline explicit UseIterator(LInstruction* instr);
195e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  inline bool Done();
196e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  inline LOperand* Current();
19783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  inline void Advance();
198d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
20083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  InputIterator input_iterator_;
20183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  DeepIterator env_iterator_;
202a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
203a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
20483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Representation of the non-empty interval [start,end[.
206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass UseInterval: public ZoneObject {
207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UseInterval(LifetimePosition start, LifetimePosition end)
209a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      : start_(start), end_(end), next_(NULL) {
210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(start.Value() < end.Value());
211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition start() const { return start_; }
214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition end() const { return end_; }
215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UseInterval* next() const { return next_; }
216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Split this interval at the given position without effecting the
218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // live range that owns it. The interval must contain the position.
219be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  void SplitAt(LifetimePosition pos, Zone* zone);
220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // If this interval intersects with other return smallest position
222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // that belongs to both of them.
223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition Intersect(const UseInterval* other) const {
224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (other->start().Value() < start_.Value()) return other->Intersect(this);
225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (other->start().Value() < end_.Value()) return other->start();
226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return LifetimePosition::Invalid();
227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool Contains(LifetimePosition point) const {
230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return start_.Value() <= point.Value() && point.Value() < end_.Value();
231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_start(LifetimePosition start) { start_ = start; }
235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_next(UseInterval* next) { next_ = next; }
236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition start_;
238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition end_;
239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UseInterval* next_;
240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  friend class LiveRange;  // Assigns to start_.
242a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
244a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Representation of a use position.
245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass UsePosition: public ZoneObject {
246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
247f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  UsePosition(LifetimePosition pos, LOperand* operand, LOperand* hint);
248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LOperand* operand() const { return operand_; }
250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool HasOperand() const { return operand_ != NULL; }
251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LOperand* hint() const { return hint_; }
2530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  bool HasHint() const;
254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool RequiresRegister() const;
255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool RegisterIsBeneficial() const;
256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition pos() const { return pos_; }
258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UsePosition* next() const { return next_; }
259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_next(UsePosition* next) { next_ = next; }
262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
263f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  LOperand* const operand_;
264f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  LOperand* const hint_;
265f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  LifetimePosition const pos_;
266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UsePosition* next_;
267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool requires_reg_;
268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool register_beneficial_;
269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  friend class LiveRange;
271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Representation of SSA values' live ranges as a collection of (continuous)
274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// intervals over the instruction ordering.
275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LiveRange: public ZoneObject {
276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const int kInvalidAssignment = 0x7fffffff;
278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
279be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  LiveRange(int id, Zone* zone);
280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UseInterval* first_interval() const { return first_interval_; }
282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UsePosition* first_pos() const { return first_pos_; }
283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LiveRange* parent() const { return parent_; }
284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; }
285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LiveRange* next() const { return next_; }
286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsChild() const { return parent() != NULL; }
287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int id() const { return id_; }
288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsFixed() const { return id_ < 0; }
289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsEmpty() const { return first_interval() == NULL; }
290be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  LOperand* CreateAssignedOperand(Zone* zone);
291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int assigned_register() const { return assigned_register_; }
292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int spill_start_index() const { return spill_start_index_; }
293be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  void set_assigned_register(int reg,
294be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                             RegisterKind register_kind,
295be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                             Zone* zone);
296be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  void MakeSpilled(Zone* zone);
297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
298a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns use position in this live range that follows both start
299a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // and last processed use position.
300a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Modifies internal state of live range!
301a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UsePosition* NextUsePosition(LifetimePosition start);
302a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns use position for which register is required in this live
304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // range and which follows both start and last processed use position
305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Modifies internal state of live range!
306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UsePosition* NextRegisterPosition(LifetimePosition start);
307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns use position for which register is beneficial in this live
309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // range and which follows both start and last processed use position
310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Modifies internal state of live range!
311a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UsePosition* NextUsePositionRegisterIsBeneficial(LifetimePosition start);
312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
313876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  // Returns use position for which register is beneficial in this live
314876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  // range and which precedes start.
315876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  UsePosition* PreviousUsePositionRegisterIsBeneficial(LifetimePosition start);
316876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Can this live range be spilled at this position.
318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool CanBeSpilled(LifetimePosition pos);
319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3205f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Split this live range at the given position which must follow the start of
3215f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // the range.
3225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // All uses following the given position will be moved from this
3235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // live range to the result live range.
324be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone);
325a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3262c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  bool IsDouble() const { return is_double_; }
327a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool HasRegisterAssigned() const {
328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return assigned_register_ != kInvalidAssignment;
329a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsSpilled() const { return spilled_; }
331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
33257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  LOperand* current_hint_operand() const {
33357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    ASSERT(current_hint_operand_ == FirstHint());
33457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return current_hint_operand_;
33557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LOperand* FirstHint() const {
33757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    UsePosition* pos = first_pos_;
33857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    while (pos != NULL && !pos->HasHint()) pos = pos->next();
339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (pos != NULL) return pos->hint();
340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return NULL;
341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
342a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition Start() const {
344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(!IsEmpty());
345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return first_interval()->start();
346a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
347a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition End() const {
349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(!IsEmpty());
350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return last_interval_->end();
351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
352a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  bool HasAllocatedSpillOperand() const;
354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LOperand* GetSpillOperand() const { return spill_operand_; }
3550a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  void SetSpillOperand(LOperand* operand);
356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void SetSpillStartIndex(int start) {
358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    spill_start_index_ = Min(start, spill_start_index_);
359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
361a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool ShouldBeAllocatedBefore(const LiveRange* other) const;
362a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool CanCover(LifetimePosition position) const;
363a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool Covers(LifetimePosition position);
364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition FirstIntersection(LiveRange* other);
365a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
366a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Add a new interval or a new use position to this live range.
367be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  void EnsureInterval(LifetimePosition start,
368be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                      LifetimePosition end,
369be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                      Zone* zone);
370be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  void AddUseInterval(LifetimePosition start,
371be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                      LifetimePosition end,
372be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                      Zone* zone);
373f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  void AddUsePosition(LifetimePosition pos,
374f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                      LOperand* operand,
375f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                      LOperand* hint,
376f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                      Zone* zone);
377a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
378a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Shorten the most recently added interval by setting a new start.
379a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ShortenTo(LifetimePosition start);
380a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
382a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // True if target overlaps an existing interval.
383a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool HasOverlap(UseInterval* target) const;
384a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Verify() const;
385a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
386a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
387a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
388be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  void ConvertOperands(Zone* zone);
389a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
390a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AdvanceLastProcessedMarker(UseInterval* to_start_of,
391a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                  LifetimePosition but_not_past) const;
392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int id_;
394a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool spilled_;
3952c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  bool is_double_;
396a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int assigned_register_;
397a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UseInterval* last_interval_;
398a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UseInterval* first_interval_;
399a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UsePosition* first_pos_;
400a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LiveRange* parent_;
401a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LiveRange* next_;
402a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // This is used as a cache, it doesn't affect correctness.
403a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  mutable UseInterval* current_interval_;
404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UsePosition* last_processed_use_;
40557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  // This is used as a cache, it's invalid outside of BuildLiveRanges.
40657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  LOperand* current_hint_operand_;
407a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LOperand* spill_operand_;
408a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int spill_start_index_;
409a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
410a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LAllocator BASE_EMBEDDED {
413a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
414b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  LAllocator(int first_virtual_register, HGraph* graph);
415a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
416a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static void TraceAlloc(const char* msg, ...);
417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
418a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Checks whether the value of a given virtual register is tagged.
419a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool HasTaggedValue(int virtual_register) const;
420a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4215f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Returns the register kind required by the given virtual register.
4225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  RegisterKind RequiredRegisterKind(int virtual_register) const;
423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
424994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  bool Allocate(LChunk* chunk);
425a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
426a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; }
427b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  const Vector<LiveRange*>* fixed_live_ranges() const {
428a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return &fixed_live_ranges_;
429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
430b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  const Vector<LiveRange*>* fixed_double_live_ranges() const {
431a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return &fixed_double_live_ranges_;
432a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
43428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  LPlatformChunk* chunk() const { return chunk_; }
435a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HGraph* graph() const { return graph_; }
436750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Isolate* isolate() const { return graph_->isolate(); }
4371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Zone* zone() { return &zone_; }
438a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
439994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  int GetVirtualRegister() {
4402bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    if (next_virtual_register_ >= LUnallocated::kMaxVirtualRegisters) {
441994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      allocation_ok_ = false;
4422bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      // Maintain the invariant that we return something below the maximum.
4432bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      return 0;
444994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    }
445994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    return next_virtual_register_++;
446994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  }
447994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
448994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  bool AllocationOk() { return allocation_ok_; }
449994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
450a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void MarkAsOsrEntry() {
451a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // There can be only one.
452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(!has_osr_entry_);
453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Simply set a flag to find and process instruction later.
454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    has_osr_entry_ = true;
455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
456a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
457a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Verify() const;
459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
46194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  BitVector* assigned_registers() {
46294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    return assigned_registers_;
46394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
46494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  BitVector* assigned_double_registers() {
46594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    return assigned_double_registers_;
46694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
46794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
469a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void MeetRegisterConstraints();
470a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ResolvePhis();
471a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void BuildLiveRanges();
472a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AllocateGeneralRegisters();
473a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AllocateDoubleRegisters();
474a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ConnectRanges();
475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ResolveControlFlow();
476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PopulatePointerMaps();
477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AllocateRegisters();
478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool CanEagerlyResolveControlFlow(HBasicBlock* block) const;
479a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  inline bool SafePointsAreInOrder() const;
480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Liveness analysis support.
482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void InitializeLivenessAnalysis();
483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  BitVector* ComputeLiveOut(HBasicBlock* block);
484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddInitialIntervals(HBasicBlock* block, BitVector* live_out);
485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ProcessInstructions(HBasicBlock* block, BitVector* live);
486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void MeetRegisterConstraints(HBasicBlock* block);
48783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  void MeetConstraintsBetween(LInstruction* first,
48883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                              LInstruction* second,
489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              int gap_index);
490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ResolvePhis(HBasicBlock* block);
491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Helper methods for building intervals.
493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LOperand* AllocateFixed(LUnallocated* operand, int pos, bool is_tagged);
494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LiveRange* LiveRangeFor(LOperand* operand);
495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Define(LifetimePosition position, LOperand* operand, LOperand* hint);
496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Use(LifetimePosition block_start,
497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org           LifetimePosition position,
498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org           LOperand* operand,
499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org           LOperand* hint);
500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddConstraintsGapMove(int index, LOperand* from, LOperand* to);
501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Helper methods for updating the life range lists.
503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddToActive(LiveRange* range);
504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddToInactive(LiveRange* range);
505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddToUnhandledSorted(LiveRange* range);
506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddToUnhandledUnsorted(LiveRange* range);
507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void SortUnhandled();
508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool UnhandledIsSorted();
509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ActiveToHandled(LiveRange* range);
510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ActiveToInactive(LiveRange* range);
511a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void InactiveToHandled(LiveRange* range);
512a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void InactiveToActive(LiveRange* range);
513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void FreeSpillSlot(LiveRange* range);
514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LOperand* TryReuseSpillSlot(LiveRange* range);
515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Helper methods for allocating registers.
517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool TryAllocateFreeReg(LiveRange* range);
518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AllocateBlockedReg(LiveRange* range);
5195f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
5205f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Live range splitting helpers.
5215f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
5225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Split the given range at the given position.
5235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // If range starts at or after the given position then the
5245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // original range is returned.
5255f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Otherwise returns the live range that starts at pos and contains
5265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // all uses from the original range that follow pos. Uses at pos will
5275f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // still be owned by the original range after splitting.
528994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos);
5295f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
5305f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Split the given range in a position from the interval [start, end].
5315f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  LiveRange* SplitBetween(LiveRange* range,
5325f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                          LifetimePosition start,
5335f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                          LifetimePosition end);
5345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
5355f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Find a lifetime position in the interval [start, end] which
5365f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // is optimal for splitting: it is either header of the outermost
5375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // loop covered by this interval or the latest possible position.
538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LifetimePosition FindOptimalSplitPos(LifetimePosition start,
539a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                       LifetimePosition end);
5405f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
5415f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Spill the given life range after position pos.
5425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void SpillAfter(LiveRange* range, LifetimePosition pos);
5435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
544e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Spill the given life range after position [start] and up to position [end].
5455f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void SpillBetween(LiveRange* range,
5465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                    LifetimePosition start,
5475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                    LifetimePosition end);
5485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Spill the given life range after position [start] and up to position [end].
550e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Range is guaranteed to be spilled at least until position [until].
551e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void SpillBetweenUntil(LiveRange* range,
552e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                         LifetimePosition start,
553e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                         LifetimePosition until,
554e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                         LifetimePosition end);
555e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5565f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void SplitAndSpillIntersecting(LiveRange* range);
5575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
558876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  // If we are trying to spill a range inside the loop try to
559876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  // hoist spill position out to the point just before the loop.
560876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  LifetimePosition FindOptimalSpillingPos(LiveRange* range,
561876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org                                          LifetimePosition pos);
562876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Spill(LiveRange* range);
564a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsBlockBoundary(LifetimePosition pos);
565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Helper methods for resolving control flow.
567a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ResolveControlFlow(LiveRange* range,
568a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          HBasicBlock* block,
569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          HBasicBlock* pred);
570a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
57194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  inline void SetLiveRangeAssignedRegister(LiveRange* range,
57294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                                           int reg,
5731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                           RegisterKind register_kind);
57494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Return parallel move that should be used to connect ranges split at the
576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // given position.
577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LParallelMove* GetConnectingParallelMove(LifetimePosition pos);
578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Return the block which contains give lifetime position.
580a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* GetBlock(LifetimePosition pos);
581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
582a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Helper methods for the fixed registers.
583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int RegisterCount() const;
584a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static int FixedLiveRangeID(int index) { return -index - 1; }
585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static int FixedDoubleLiveRangeID(int index);
586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LiveRange* FixedLiveRangeFor(int index);
587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LiveRange* FixedDoubleLiveRangeFor(int index);
588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LiveRange* LiveRangeFor(int index);
589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HPhi* LookupPhi(LOperand* operand) const;
59083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  LGap* GetLastGap(HBasicBlock* block);
591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  const char* RegisterName(int allocation_index);
5935f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
59483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  inline bool IsGapAt(int index);
595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
59683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  inline LInstruction* InstructionAt(int index);
59783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
59883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  inline LGap* GapAt(int index);
59983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
6001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Zone zone_;
601a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
60228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  LPlatformChunk* chunk_;
603994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // During liveness analysis keep a mapping from block id to live_in sets
605a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // for blocks already analyzed.
606a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<BitVector*> live_in_sets_;
607a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
608a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Liveness analysis results.
609a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<LiveRange*> live_ranges_;
610a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Lists of live ranges
612a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  EmbeddedVector<LiveRange*, Register::kMaxNumAllocatableRegisters>
613b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      fixed_live_ranges_;
614a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumAllocatableRegisters>
615b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      fixed_double_live_ranges_;
616a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<LiveRange*> unhandled_live_ranges_;
617a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<LiveRange*> active_live_ranges_;
618a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<LiveRange*> inactive_live_ranges_;
619a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<LiveRange*> reusable_slots_;
620a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
621a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Next virtual register number to be assigned to temporaries.
622a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int next_virtual_register_;
6235d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  int first_artificial_register_;
6245d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  GrowableBitVector double_artificial_registers_;
625a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  RegisterKind mode_;
627a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int num_registers_;
628a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
62994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  BitVector* assigned_registers_;
63094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  BitVector* assigned_double_registers_;
63194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
632a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HGraph* graph_;
633a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
634a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool has_osr_entry_;
635a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
636be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // Indicates success or failure during register allocation.
637be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  bool allocation_ok_;
638be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
639e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#ifdef DEBUG
640e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  LifetimePosition allocation_finger_;
641e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif
642e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
643a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DISALLOW_COPY_AND_ASSIGN(LAllocator);
644a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
645a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
646a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgclass LAllocatorPhase : public CompilationPhase {
6481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org public:
6491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  LAllocatorPhase(const char* name, LAllocator* allocator);
6501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ~LAllocatorPhase();
6511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
6521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org private:
6531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  LAllocator* allocator_;
6541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  unsigned allocator_zone_start_allocation_size_;
6551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
6561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  DISALLOW_COPY_AND_ASSIGN(LAllocatorPhase);
6571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org};
6581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
6591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
660a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} }  // namespace v8::internal
661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif  // V8_LITHIUM_ALLOCATOR_H_
663