Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(617)

Side by Side Diff: src/compiler/register-allocator.h

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_LITHIUM_ALLOCATOR_H_ 5 #ifndef V8_REGISTER_ALLOCATOR_H_
6 #define V8_LITHIUM_ALLOCATOR_H_ 6 #define V8_REGISTER_ALLOCATOR_H_
7
8 #include "src/v8.h"
9 7
10 #include "src/allocation.h" 8 #include "src/allocation.h"
11 #include "src/lithium.h" 9 #include "src/compiler/instruction.h"
10 #include "src/compiler/node.h"
11 #include "src/compiler/schedule.h"
12 #include "src/macro-assembler.h"
12 #include "src/zone.h" 13 #include "src/zone.h"
13 14
14 namespace v8 { 15 namespace v8 {
15 namespace internal { 16 namespace internal {
16 17
17 // Forward declarations. 18 // Forward declarations.
18 class HBasicBlock;
19 class HGraph;
20 class HInstruction;
21 class HPhi;
22 class HTracer;
23 class HValue;
24 class BitVector; 19 class BitVector;
25 class StringStream; 20 class InstructionOperand;
21 class UnallocatedOperand;
22 class ParallelMove;
23 class PointerMap;
26 24
27 class LPlatformChunk; 25 namespace compiler {
28 class LOperand; 26
29 class LUnallocated; 27 enum RegisterKind {
30 class LGap; 28 UNALLOCATED_REGISTERS,
31 class LParallelMove; 29 GENERAL_REGISTERS,
32 class LPointerMap; 30 DOUBLE_REGISTERS
31 };
33 32
34 33
35 // This class represents a single point of a LOperand's lifetime. 34 // This class represents a single point of a InstructionOperand's lifetime. For
36 // For each lithium instruction there are exactly two lifetime positions: 35 // each instruction there are exactly two lifetime positions: the beginning and
37 // the beginning and the end of the instruction. Lifetime positions for 36 // the end of the instruction. Lifetime positions for different instructions are
38 // different lithium instructions are disjoint. 37 // disjoint.
39 class LifetimePosition { 38 class LifetimePosition {
40 public: 39 public:
41 // Return the lifetime position that corresponds to the beginning of 40 // Return the lifetime position that corresponds to the beginning of
42 // the instruction with the given index. 41 // the instruction with the given index.
43 static LifetimePosition FromInstructionIndex(int index) { 42 static LifetimePosition FromInstructionIndex(int index) {
44 return LifetimePosition(index * kStep); 43 return LifetimePosition(index * kStep);
45 } 44 }
46 45
47 // Returns a numeric representation of this lifetime position. 46 // Returns a numeric representation of this lifetime position.
48 int Value() const { 47 int Value() const {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 110
112 // Code relies on kStep being a power of two. 111 // Code relies on kStep being a power of two.
113 STATIC_ASSERT(IS_POWER_OF_TWO(kStep)); 112 STATIC_ASSERT(IS_POWER_OF_TWO(kStep));
114 113
115 explicit LifetimePosition(int value) : value_(value) { } 114 explicit LifetimePosition(int value) : value_(value) { }
116 115
117 int value_; 116 int value_;
118 }; 117 };
119 118
120 119
121 enum RegisterKind {
122 UNALLOCATED_REGISTERS,
123 GENERAL_REGISTERS,
124 DOUBLE_REGISTERS
125 };
126
127
128 // A register-allocator view of a Lithium instruction. It contains the id of
129 // the output operand and a list of input operand uses.
130
131 class LInstruction;
132 class LEnvironment;
133
134 // Iterator for non-null temp operands.
135 class TempIterator BASE_EMBEDDED {
136 public:
137 inline explicit TempIterator(LInstruction* instr);
138 inline bool Done();
139 inline LOperand* Current();
140 inline void Advance();
141
142 private:
143 inline void SkipUninteresting();
144 LInstruction* instr_;
145 int limit_;
146 int current_;
147 };
148
149
150 // Iterator for non-constant input operands.
151 class InputIterator BASE_EMBEDDED {
152 public:
153 inline explicit InputIterator(LInstruction* instr);
154 inline bool Done();
155 inline LOperand* Current();
156 inline void Advance();
157
158 private:
159 inline void SkipUninteresting();
160 LInstruction* instr_;
161 int limit_;
162 int current_;
163 };
164
165
166 class UseIterator BASE_EMBEDDED {
167 public:
168 inline explicit UseIterator(LInstruction* instr);
169 inline bool Done();
170 inline LOperand* Current();
171 inline void Advance();
172
173 private:
174 InputIterator input_iterator_;
175 DeepIterator env_iterator_;
176 };
177
178
179 // Representation of the non-empty interval [start,end[. 120 // Representation of the non-empty interval [start,end[.
180 class UseInterval: public ZoneObject { 121 class UseInterval: public ZoneObject {
181 public: 122 public:
182 UseInterval(LifetimePosition start, LifetimePosition end) 123 UseInterval(LifetimePosition start, LifetimePosition end)
183 : start_(start), end_(end), next_(NULL) { 124 : start_(start), end_(end), next_(NULL) {
184 ASSERT(start.Value() < end.Value()); 125 ASSERT(start.Value() < end.Value());
185 } 126 }
186 127
187 LifetimePosition start() const { return start_; } 128 LifetimePosition start() const { return start_; }
188 LifetimePosition end() const { return end_; } 129 LifetimePosition end() const { return end_; }
189 UseInterval* next() const { return next_; } 130 UseInterval* next() const { return next_; }
190 131
191 // Split this interval at the given position without effecting the 132 // Split this interval at the given position without effecting the
192 // live range that owns it. The interval must contain the position. 133 // live range that owns it. The interval must contain the position.
193 void SplitAt(LifetimePosition pos, Zone* zone); 134 void SplitAt(LifetimePosition pos, Zone* zone);
194 135
195 // If this interval intersects with other return smallest position 136 // If this interval intersects with other return smallest position
196 // that belongs to both of them. 137 // that belongs to both of them.
197 LifetimePosition Intersect(const UseInterval* other) const { 138 LifetimePosition Intersect(const UseInterval* other) const {
198 if (other->start().Value() < start_.Value()) return other->Intersect(this); 139 if (other->start().Value() < start_.Value()) return other->Intersect(this);
199 if (other->start().Value() < end_.Value()) return other->start(); 140 if (other->start().Value() < end_.Value()) return other->start();
200 return LifetimePosition::Invalid(); 141 return LifetimePosition::Invalid();
201 } 142 }
202 143
203 bool Contains(LifetimePosition point) const { 144 bool Contains(LifetimePosition point) const {
204 return start_.Value() <= point.Value() && point.Value() < end_.Value(); 145 return start_.Value() <= point.Value() && point.Value() < end_.Value();
205 } 146 }
206 147
207 private:
208 void set_start(LifetimePosition start) { start_ = start; } 148 void set_start(LifetimePosition start) { start_ = start; }
209 void set_next(UseInterval* next) { next_ = next; } 149 void set_next(UseInterval* next) { next_ = next; }
210 150
211 LifetimePosition start_; 151 LifetimePosition start_;
212 LifetimePosition end_; 152 LifetimePosition end_;
213 UseInterval* next_; 153 UseInterval* next_;
214
215 friend class LiveRange; // Assigns to start_.
216 }; 154 };
217 155
218 // Representation of a use position. 156 // Representation of a use position.
219 class UsePosition: public ZoneObject { 157 class UsePosition: public ZoneObject {
220 public: 158 public:
221 UsePosition(LifetimePosition pos, LOperand* operand, LOperand* hint); 159 UsePosition(LifetimePosition pos, InstructionOperand* operand,
160 InstructionOperand* hint);
222 161
223 LOperand* operand() const { return operand_; } 162 InstructionOperand* operand() const { return operand_; }
224 bool HasOperand() const { return operand_ != NULL; } 163 bool HasOperand() const { return operand_ != NULL; }
225 164
226 LOperand* hint() const { return hint_; } 165 InstructionOperand* hint() const { return hint_; }
227 bool HasHint() const; 166 bool HasHint() const;
228 bool RequiresRegister() const; 167 bool RequiresRegister() const;
229 bool RegisterIsBeneficial() const; 168 bool RegisterIsBeneficial() const;
230 169
231 LifetimePosition pos() const { return pos_; } 170 LifetimePosition pos() const { return pos_; }
232 UsePosition* next() const { return next_; } 171 UsePosition* next() const { return next_; }
233 172
234 private:
235 void set_next(UsePosition* next) { next_ = next; } 173 void set_next(UsePosition* next) { next_ = next; }
236 174
237 LOperand* const operand_; 175 InstructionOperand* const operand_;
238 LOperand* const hint_; 176 InstructionOperand* const hint_;
239 LifetimePosition const pos_; 177 LifetimePosition const pos_;
240 UsePosition* next_; 178 UsePosition* next_;
241 bool requires_reg_; 179 bool requires_reg_;
242 bool register_beneficial_; 180 bool register_beneficial_;
243
244 friend class LiveRange;
245 }; 181 };
246 182
247 // Representation of SSA values' live ranges as a collection of (continuous) 183 // Representation of SSA values' live ranges as a collection of (continuous)
248 // intervals over the instruction ordering. 184 // intervals over the instruction ordering.
249 class LiveRange: public ZoneObject { 185 class LiveRange: public ZoneObject {
250 public: 186 public:
251 static const int kInvalidAssignment = 0x7fffffff; 187 static const int kInvalidAssignment = 0x7fffffff;
252 188
253 LiveRange(int id, Zone* zone); 189 LiveRange(int id, Zone* zone);
254 190
255 UseInterval* first_interval() const { return first_interval_; } 191 UseInterval* first_interval() const { return first_interval_; }
256 UsePosition* first_pos() const { return first_pos_; } 192 UsePosition* first_pos() const { return first_pos_; }
257 LiveRange* parent() const { return parent_; } 193 LiveRange* parent() const { return parent_; }
258 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } 194 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; }
259 LiveRange* next() const { return next_; } 195 LiveRange* next() const { return next_; }
260 bool IsChild() const { return parent() != NULL; } 196 bool IsChild() const { return parent() != NULL; }
261 int id() const { return id_; } 197 int id() const { return id_; }
262 bool IsFixed() const { return id_ < 0; } 198 bool IsFixed() const { return id_ < 0; }
263 bool IsEmpty() const { return first_interval() == NULL; } 199 bool IsEmpty() const { return first_interval() == NULL; }
264 LOperand* CreateAssignedOperand(Zone* zone); 200 InstructionOperand* CreateAssignedOperand(Zone* zone);
265 int assigned_register() const { return assigned_register_; } 201 int assigned_register() const { return assigned_register_; }
266 int spill_start_index() const { return spill_start_index_; } 202 int spill_start_index() const { return spill_start_index_; }
267 void set_assigned_register(int reg, Zone* zone); 203 void set_assigned_register(int reg, Zone* zone);
268 void MakeSpilled(Zone* zone); 204 void MakeSpilled(Zone* zone);
205 bool is_phi() const { return is_phi_; }
206 void set_is_phi(bool is_phi) { is_phi_ = is_phi; }
207 bool is_non_loop_phi() const { return is_non_loop_phi_; }
208 void set_is_non_loop_phi(bool is_non_loop_phi) {
209 is_non_loop_phi_ = is_non_loop_phi;
210 }
269 211
270 // Returns use position in this live range that follows both start 212 // Returns use position in this live range that follows both start
271 // and last processed use position. 213 // and last processed use position.
272 // Modifies internal state of live range! 214 // Modifies internal state of live range!
273 UsePosition* NextUsePosition(LifetimePosition start); 215 UsePosition* NextUsePosition(LifetimePosition start);
274 216
275 // Returns use position for which register is required in this live 217 // Returns use position for which register is required in this live
276 // range and which follows both start and last processed use position 218 // range and which follows both start and last processed use position
277 // Modifies internal state of live range! 219 // Modifies internal state of live range!
278 UsePosition* NextRegisterPosition(LifetimePosition start); 220 UsePosition* NextRegisterPosition(LifetimePosition start);
(...skipping 15 matching lines...) Expand all
294 // All uses following the given position will be moved from this 236 // All uses following the given position will be moved from this
295 // live range to the result live range. 237 // live range to the result live range.
296 void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone); 238 void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone);
297 239
298 RegisterKind Kind() const { return kind_; } 240 RegisterKind Kind() const { return kind_; }
299 bool HasRegisterAssigned() const { 241 bool HasRegisterAssigned() const {
300 return assigned_register_ != kInvalidAssignment; 242 return assigned_register_ != kInvalidAssignment;
301 } 243 }
302 bool IsSpilled() const { return spilled_; } 244 bool IsSpilled() const { return spilled_; }
303 245
304 LOperand* current_hint_operand() const { 246 InstructionOperand* current_hint_operand() const {
305 ASSERT(current_hint_operand_ == FirstHint()); 247 ASSERT(current_hint_operand_ == FirstHint());
306 return current_hint_operand_; 248 return current_hint_operand_;
307 } 249 }
308 LOperand* FirstHint() const { 250 InstructionOperand* FirstHint() const {
309 UsePosition* pos = first_pos_; 251 UsePosition* pos = first_pos_;
310 while (pos != NULL && !pos->HasHint()) pos = pos->next(); 252 while (pos != NULL && !pos->HasHint()) pos = pos->next();
311 if (pos != NULL) return pos->hint(); 253 if (pos != NULL) return pos->hint();
312 return NULL; 254 return NULL;
313 } 255 }
314 256
315 LifetimePosition Start() const { 257 LifetimePosition Start() const {
316 ASSERT(!IsEmpty()); 258 ASSERT(!IsEmpty());
317 return first_interval()->start(); 259 return first_interval()->start();
318 } 260 }
319 261
320 LifetimePosition End() const { 262 LifetimePosition End() const {
321 ASSERT(!IsEmpty()); 263 ASSERT(!IsEmpty());
322 return last_interval_->end(); 264 return last_interval_->end();
323 } 265 }
324 266
325 bool HasAllocatedSpillOperand() const; 267 bool HasAllocatedSpillOperand() const;
326 LOperand* GetSpillOperand() const { return spill_operand_; } 268 InstructionOperand* GetSpillOperand() const { return spill_operand_; }
327 void SetSpillOperand(LOperand* operand); 269 void SetSpillOperand(InstructionOperand* operand);
328 270
329 void SetSpillStartIndex(int start) { 271 void SetSpillStartIndex(int start) {
330 spill_start_index_ = Min(start, spill_start_index_); 272 spill_start_index_ = Min(start, spill_start_index_);
331 } 273 }
332 274
333 bool ShouldBeAllocatedBefore(const LiveRange* other) const; 275 bool ShouldBeAllocatedBefore(const LiveRange* other) const;
334 bool CanCover(LifetimePosition position) const; 276 bool CanCover(LifetimePosition position) const;
335 bool Covers(LifetimePosition position); 277 bool Covers(LifetimePosition position);
336 LifetimePosition FirstIntersection(LiveRange* other); 278 LifetimePosition FirstIntersection(LiveRange* other);
337 279
338 // Add a new interval or a new use position to this live range. 280 // Add a new interval or a new use position to this live range.
339 void EnsureInterval(LifetimePosition start, 281 void EnsureInterval(LifetimePosition start,
340 LifetimePosition end, 282 LifetimePosition end,
341 Zone* zone); 283 Zone* zone);
342 void AddUseInterval(LifetimePosition start, 284 void AddUseInterval(LifetimePosition start,
343 LifetimePosition end, 285 LifetimePosition end,
344 Zone* zone); 286 Zone* zone);
345 void AddUsePosition(LifetimePosition pos, 287 void AddUsePosition(LifetimePosition pos, InstructionOperand* operand,
346 LOperand* operand, 288 InstructionOperand* hint, Zone* zone);
347 LOperand* hint,
348 Zone* zone);
349 289
350 // Shorten the most recently added interval by setting a new start. 290 // Shorten the most recently added interval by setting a new start.
351 void ShortenTo(LifetimePosition start); 291 void ShortenTo(LifetimePosition start);
352 292
353 #ifdef DEBUG 293 #ifdef DEBUG
354 // True if target overlaps an existing interval. 294 // True if target overlaps an existing interval.
355 bool HasOverlap(UseInterval* target) const; 295 bool HasOverlap(UseInterval* target) const;
356 void Verify() const; 296 void Verify() const;
357 #endif 297 #endif
358 298
359 private: 299 private:
360 void ConvertOperands(Zone* zone); 300 void ConvertOperands(Zone* zone);
361 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; 301 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
362 void AdvanceLastProcessedMarker(UseInterval* to_start_of, 302 void AdvanceLastProcessedMarker(UseInterval* to_start_of,
363 LifetimePosition but_not_past) const; 303 LifetimePosition but_not_past) const;
364 304
365 int id_; 305 int id_;
366 bool spilled_; 306 bool spilled_;
307 bool is_phi_;
308 bool is_non_loop_phi_;
367 RegisterKind kind_; 309 RegisterKind kind_;
368 int assigned_register_; 310 int assigned_register_;
369 UseInterval* last_interval_; 311 UseInterval* last_interval_;
370 UseInterval* first_interval_; 312 UseInterval* first_interval_;
371 UsePosition* first_pos_; 313 UsePosition* first_pos_;
372 LiveRange* parent_; 314 LiveRange* parent_;
373 LiveRange* next_; 315 LiveRange* next_;
374 // This is used as a cache, it doesn't affect correctness. 316 // This is used as a cache, it doesn't affect correctness.
375 mutable UseInterval* current_interval_; 317 mutable UseInterval* current_interval_;
376 UsePosition* last_processed_use_; 318 UsePosition* last_processed_use_;
377 // This is used as a cache, it's invalid outside of BuildLiveRanges. 319 // This is used as a cache, it's invalid outside of BuildLiveRanges.
378 LOperand* current_hint_operand_; 320 InstructionOperand* current_hint_operand_;
379 LOperand* spill_operand_; 321 InstructionOperand* spill_operand_;
380 int spill_start_index_; 322 int spill_start_index_;
381 323
382 friend class LAllocator; // Assigns to kind_. 324 friend class RegisterAllocator; // Assigns to kind_.
383 }; 325 };
384 326
385 327
386 class LAllocator BASE_EMBEDDED { 328 class RegisterAllocator BASE_EMBEDDED {
387 public: 329 public:
388 LAllocator(int first_virtual_register, HGraph* graph); 330 explicit RegisterAllocator(InstructionSequence* code);
389 331
390 static void TraceAlloc(const char* msg, ...); 332 static void TraceAlloc(const char* msg, ...);
391 333
392 // Checks whether the value of a given virtual register is tagged. 334 // Checks whether the value of a given virtual register is a reference.
335 // TODO(titzer): rename this to IsReference.
393 bool HasTaggedValue(int virtual_register) const; 336 bool HasTaggedValue(int virtual_register) const;
394 337
395 // Returns the register kind required by the given virtual register. 338 // Returns the register kind required by the given virtual register.
396 RegisterKind RequiredRegisterKind(int virtual_register) const; 339 RegisterKind RequiredRegisterKind(int virtual_register) const;
397 340
398 bool Allocate(LChunk* chunk); 341 bool Allocate();
399 342
400 const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; } 343 const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; }
401 const Vector<LiveRange*>* fixed_live_ranges() const { 344 const Vector<LiveRange*>* fixed_live_ranges() const {
402 return &fixed_live_ranges_; 345 return &fixed_live_ranges_;
403 } 346 }
404 const Vector<LiveRange*>* fixed_double_live_ranges() const { 347 const Vector<LiveRange*>* fixed_double_live_ranges() const {
405 return &fixed_double_live_ranges_; 348 return &fixed_double_live_ranges_;
406 } 349 }
407 350
408 LPlatformChunk* chunk() const { return chunk_; } 351 inline InstructionSequence* code() const { return code_; }
409 HGraph* graph() const { return graph_; } 352
410 Isolate* isolate() const { return graph_->isolate(); } 353 // This zone is for datastructures only needed during register allocation.
411 Zone* zone() { return &zone_; } 354 inline Zone* zone() { return &zone_; }
355
356 // This zone is for InstructionOperands and moves that live beyond register
357 // allocation.
358 inline Zone* code_zone() { return code()->zone(); }
412 359
413 int GetVirtualRegister() { 360 int GetVirtualRegister() {
414 if (next_virtual_register_ >= LUnallocated::kMaxVirtualRegisters) { 361 int vreg = code()->NextVirtualRegister();
362 if (vreg >= UnallocatedOperand::kMaxVirtualRegisters) {
415 allocation_ok_ = false; 363 allocation_ok_ = false;
416 // Maintain the invariant that we return something below the maximum. 364 // Maintain the invariant that we return something below the maximum.
417 return 0; 365 return 0;
418 } 366 }
419 return next_virtual_register_++; 367 return vreg;
420 } 368 }
421 369
422 bool AllocationOk() { return allocation_ok_; } 370 bool AllocationOk() { return allocation_ok_; }
423 371
424 void MarkAsOsrEntry() {
425 // There can be only one.
426 ASSERT(!has_osr_entry_);
427 // Simply set a flag to find and process instruction later.
428 has_osr_entry_ = true;
429 }
430
431 #ifdef DEBUG 372 #ifdef DEBUG
432 void Verify() const; 373 void Verify() const;
433 #endif 374 #endif
434 375
435 BitVector* assigned_registers() { 376 BitVector* assigned_registers() {
436 return assigned_registers_; 377 return assigned_registers_;
437 } 378 }
438 BitVector* assigned_double_registers() { 379 BitVector* assigned_double_registers() {
439 return assigned_double_registers_; 380 return assigned_double_registers_;
440 } 381 }
441 382
442 private: 383 private:
443 void MeetRegisterConstraints(); 384 void MeetRegisterConstraints();
444 void ResolvePhis(); 385 void ResolvePhis();
445 void BuildLiveRanges(); 386 void BuildLiveRanges();
446 void AllocateGeneralRegisters(); 387 void AllocateGeneralRegisters();
447 void AllocateDoubleRegisters(); 388 void AllocateDoubleRegisters();
448 void ConnectRanges(); 389 void ConnectRanges();
449 void ResolveControlFlow(); 390 void ResolveControlFlow();
450 void PopulatePointerMaps(); 391 void PopulatePointerMaps(); // TODO(titzer): rename to PopulateReferenceMaps.
451 void AllocateRegisters(); 392 void AllocateRegisters();
452 bool CanEagerlyResolveControlFlow(HBasicBlock* block) const; 393 bool CanEagerlyResolveControlFlow(BasicBlock* block) const;
453 inline bool SafePointsAreInOrder() const; 394 inline bool SafePointsAreInOrder() const;
454 395
455 // Liveness analysis support. 396 // Liveness analysis support.
456 void InitializeLivenessAnalysis(); 397 void InitializeLivenessAnalysis();
457 BitVector* ComputeLiveOut(HBasicBlock* block); 398 BitVector* ComputeLiveOut(BasicBlock* block);
458 void AddInitialIntervals(HBasicBlock* block, BitVector* live_out); 399 void AddInitialIntervals(BasicBlock* block, BitVector* live_out);
459 void ProcessInstructions(HBasicBlock* block, BitVector* live); 400 bool IsOutputRegisterOf(Instruction* instr, int index);
460 void MeetRegisterConstraints(HBasicBlock* block); 401 bool IsOutputDoubleRegisterOf(Instruction* instr, int index);
461 void MeetConstraintsBetween(LInstruction* first, 402 void ProcessInstructions(BasicBlock* block, BitVector* live);
462 LInstruction* second, 403 void MeetRegisterConstraints(BasicBlock* block);
404 void MeetConstraintsBetween(Instruction* first,
405 Instruction* second,
463 int gap_index); 406 int gap_index);
464 void ResolvePhis(HBasicBlock* block); 407 void ResolvePhis(BasicBlock* block);
465 408
466 // Helper methods for building intervals. 409 // Helper methods for building intervals.
467 LOperand* AllocateFixed(LUnallocated* operand, int pos, bool is_tagged); 410 InstructionOperand* AllocateFixed(UnallocatedOperand* operand, int pos,
468 LiveRange* LiveRangeFor(LOperand* operand); 411 bool is_tagged);
469 void Define(LifetimePosition position, LOperand* operand, LOperand* hint); 412 LiveRange* LiveRangeFor(InstructionOperand* operand);
470 void Use(LifetimePosition block_start, 413 void Define(LifetimePosition position, InstructionOperand* operand,
471 LifetimePosition position, 414 InstructionOperand* hint);
472 LOperand* operand, 415 void Use(LifetimePosition block_start, LifetimePosition position,
473 LOperand* hint); 416 InstructionOperand* operand, InstructionOperand* hint);
474 void AddConstraintsGapMove(int index, LOperand* from, LOperand* to); 417 void AddConstraintsGapMove(int index, InstructionOperand* from,
418 InstructionOperand* to);
475 419
476 // Helper methods for updating the life range lists. 420 // Helper methods for updating the life range lists.
477 void AddToActive(LiveRange* range); 421 void AddToActive(LiveRange* range);
478 void AddToInactive(LiveRange* range); 422 void AddToInactive(LiveRange* range);
479 void AddToUnhandledSorted(LiveRange* range); 423 void AddToUnhandledSorted(LiveRange* range);
480 void AddToUnhandledUnsorted(LiveRange* range); 424 void AddToUnhandledUnsorted(LiveRange* range);
481 void SortUnhandled(); 425 void SortUnhandled();
482 bool UnhandledIsSorted(); 426 bool UnhandledIsSorted();
483 void ActiveToHandled(LiveRange* range); 427 void ActiveToHandled(LiveRange* range);
484 void ActiveToInactive(LiveRange* range); 428 void ActiveToInactive(LiveRange* range);
485 void InactiveToHandled(LiveRange* range); 429 void InactiveToHandled(LiveRange* range);
486 void InactiveToActive(LiveRange* range); 430 void InactiveToActive(LiveRange* range);
487 void FreeSpillSlot(LiveRange* range); 431 void FreeSpillSlot(LiveRange* range);
488 LOperand* TryReuseSpillSlot(LiveRange* range); 432 InstructionOperand* TryReuseSpillSlot(LiveRange* range);
489 433
490 // Helper methods for allocating registers. 434 // Helper methods for allocating registers.
491 bool TryAllocateFreeReg(LiveRange* range); 435 bool TryAllocateFreeReg(LiveRange* range);
492 void AllocateBlockedReg(LiveRange* range); 436 void AllocateBlockedReg(LiveRange* range);
493 437
494 // Live range splitting helpers. 438 // Live range splitting helpers.
495 439
496 // Split the given range at the given position. 440 // Split the given range at the given position.
497 // If range starts at or after the given position then the 441 // If range starts at or after the given position then the
498 // original range is returned. 442 // original range is returned.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 // If we are trying to spill a range inside the loop try to 476 // If we are trying to spill a range inside the loop try to
533 // hoist spill position out to the point just before the loop. 477 // hoist spill position out to the point just before the loop.
534 LifetimePosition FindOptimalSpillingPos(LiveRange* range, 478 LifetimePosition FindOptimalSpillingPos(LiveRange* range,
535 LifetimePosition pos); 479 LifetimePosition pos);
536 480
537 void Spill(LiveRange* range); 481 void Spill(LiveRange* range);
538 bool IsBlockBoundary(LifetimePosition pos); 482 bool IsBlockBoundary(LifetimePosition pos);
539 483
540 // Helper methods for resolving control flow. 484 // Helper methods for resolving control flow.
541 void ResolveControlFlow(LiveRange* range, 485 void ResolveControlFlow(LiveRange* range,
542 HBasicBlock* block, 486 BasicBlock* block,
543 HBasicBlock* pred); 487 BasicBlock* pred);
544 488
545 inline void SetLiveRangeAssignedRegister(LiveRange* range, int reg); 489 inline void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
546 490
547 // Return parallel move that should be used to connect ranges split at the 491 // Return parallel move that should be used to connect ranges split at the
548 // given position. 492 // given position.
549 LParallelMove* GetConnectingParallelMove(LifetimePosition pos); 493 ParallelMove* GetConnectingParallelMove(LifetimePosition pos);
550 494
551 // Return the block which contains give lifetime position. 495 // Return the block which contains give lifetime position.
552 HBasicBlock* GetBlock(LifetimePosition pos); 496 BasicBlock* GetBlock(LifetimePosition pos);
553 497
554 // Helper methods for the fixed registers. 498 // Helper methods for the fixed registers.
555 int RegisterCount() const; 499 int RegisterCount() const;
556 static int FixedLiveRangeID(int index) { return -index - 1; } 500 static int FixedLiveRangeID(int index) { return -index - 1; }
557 static int FixedDoubleLiveRangeID(int index); 501 static int FixedDoubleLiveRangeID(int index);
558 LiveRange* FixedLiveRangeFor(int index); 502 LiveRange* FixedLiveRangeFor(int index);
559 LiveRange* FixedDoubleLiveRangeFor(int index); 503 LiveRange* FixedDoubleLiveRangeFor(int index);
560 LiveRange* LiveRangeFor(int index); 504 LiveRange* LiveRangeFor(int index);
561 HPhi* LookupPhi(LOperand* operand) const; 505 GapInstruction* GetLastGap(BasicBlock* block);
562 LGap* GetLastGap(HBasicBlock* block);
563 506
564 const char* RegisterName(int allocation_index); 507 const char* RegisterName(int allocation_index);
565 508
566 inline bool IsGapAt(int index); 509 inline Instruction* InstructionAt(int index) {
567 510 return code()->InstructionAt(index);
568 inline LInstruction* InstructionAt(int index); 511 }
569
570 inline LGap* GapAt(int index);
571 512
572 Zone zone_; 513 Zone zone_;
573 514 InstructionSequence* code_;
574 LPlatformChunk* chunk_;
575 515
576 // During liveness analysis keep a mapping from block id to live_in sets 516 // During liveness analysis keep a mapping from block id to live_in sets
577 // for blocks already analyzed. 517 // for blocks already analyzed.
578 ZoneList<BitVector*> live_in_sets_; 518 ZoneList<BitVector*> live_in_sets_;
579 519
580 // Liveness analysis results. 520 // Liveness analysis results.
581 ZoneList<LiveRange*> live_ranges_; 521 ZoneList<LiveRange*> live_ranges_;
582 522
583 // Lists of live ranges 523 // Lists of live ranges
584 EmbeddedVector<LiveRange*, Register::kMaxNumAllocatableRegisters> 524 EmbeddedVector<LiveRange*, Register::kMaxNumAllocatableRegisters>
585 fixed_live_ranges_; 525 fixed_live_ranges_;
586 EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumAllocatableRegisters> 526 EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumAllocatableRegisters>
587 fixed_double_live_ranges_; 527 fixed_double_live_ranges_;
588 ZoneList<LiveRange*> unhandled_live_ranges_; 528 ZoneList<LiveRange*> unhandled_live_ranges_;
589 ZoneList<LiveRange*> active_live_ranges_; 529 ZoneList<LiveRange*> active_live_ranges_;
590 ZoneList<LiveRange*> inactive_live_ranges_; 530 ZoneList<LiveRange*> inactive_live_ranges_;
591 ZoneList<LiveRange*> reusable_slots_; 531 ZoneList<LiveRange*> reusable_slots_;
592 532
593 // Next virtual register number to be assigned to temporaries.
594 int next_virtual_register_;
595 int first_artificial_register_;
596 GrowableBitVector double_artificial_registers_;
597
598 RegisterKind mode_; 533 RegisterKind mode_;
599 int num_registers_; 534 int num_registers_;
600 535
601 BitVector* assigned_registers_; 536 BitVector* assigned_registers_;
602 BitVector* assigned_double_registers_; 537 BitVector* assigned_double_registers_;
603 538
604 HGraph* graph_;
605
606 bool has_osr_entry_;
607
608 // Indicates success or failure during register allocation. 539 // Indicates success or failure during register allocation.
609 bool allocation_ok_; 540 bool allocation_ok_;
610 541
611 #ifdef DEBUG 542 #ifdef DEBUG
612 LifetimePosition allocation_finger_; 543 LifetimePosition allocation_finger_;
613 #endif 544 #endif
614 545
615 DISALLOW_COPY_AND_ASSIGN(LAllocator); 546 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator);
616 }; 547 };
617 548
618 549
619 class LAllocatorPhase : public CompilationPhase { 550 class RegisterAllocatorPhase : public CompilationPhase {
620 public: 551 public:
621 LAllocatorPhase(const char* name, LAllocator* allocator); 552 RegisterAllocatorPhase(const char* name, RegisterAllocator* allocator);
622 ~LAllocatorPhase(); 553 ~RegisterAllocatorPhase();
623 554
624 private: 555 private:
625 LAllocator* allocator_; 556 RegisterAllocator* allocator_;
626 unsigned allocator_zone_start_allocation_size_; 557 unsigned allocator_zone_start_allocation_size_;
627 558
628 DISALLOW_COPY_AND_ASSIGN(LAllocatorPhase); 559 DISALLOW_COPY_AND_ASSIGN(RegisterAllocatorPhase);
629 }; 560 };
630 561
631 562
632 } } // namespace v8::internal 563 } } } // namespace v8::internal::compiler
633 564
634 #endif // V8_LITHIUM_ALLOCATOR_H_ 565 #endif // V8_REGISTER_ALLOCATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698