OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 : start_(start), end_(end), next_(NULL) { | 209 : start_(start), end_(end), next_(NULL) { |
210 ASSERT(start.Value() < end.Value()); | 210 ASSERT(start.Value() < end.Value()); |
211 } | 211 } |
212 | 212 |
213 LifetimePosition start() const { return start_; } | 213 LifetimePosition start() const { return start_; } |
214 LifetimePosition end() const { return end_; } | 214 LifetimePosition end() const { return end_; } |
215 UseInterval* next() const { return next_; } | 215 UseInterval* next() const { return next_; } |
216 | 216 |
217 // Split this interval at the given position without effecting the | 217 // Split this interval at the given position without effecting the |
218 // live range that owns it. The interval must contain the position. | 218 // live range that owns it. The interval must contain the position. |
219 void SplitAt(LifetimePosition pos); | 219 void SplitAt(LifetimePosition pos, Zone* zone); |
220 | 220 |
221 // If this interval intersects with other return smallest position | 221 // If this interval intersects with other return smallest position |
222 // that belongs to both of them. | 222 // that belongs to both of them. |
223 LifetimePosition Intersect(const UseInterval* other) const { | 223 LifetimePosition Intersect(const UseInterval* other) const { |
224 if (other->start().Value() < start_.Value()) return other->Intersect(this); | 224 if (other->start().Value() < start_.Value()) return other->Intersect(this); |
225 if (other->start().Value() < end_.Value()) return other->start(); | 225 if (other->start().Value() < end_.Value()) return other->start(); |
226 return LifetimePosition::Invalid(); | 226 return LifetimePosition::Invalid(); |
227 } | 227 } |
228 | 228 |
229 bool Contains(LifetimePosition point) const { | 229 bool Contains(LifetimePosition point) const { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 | 270 |
271 friend class LiveRange; | 271 friend class LiveRange; |
272 }; | 272 }; |
273 | 273 |
274 // Representation of SSA values' live ranges as a collection of (continuous) | 274 // Representation of SSA values' live ranges as a collection of (continuous) |
275 // intervals over the instruction ordering. | 275 // intervals over the instruction ordering. |
276 class LiveRange: public ZoneObject { | 276 class LiveRange: public ZoneObject { |
277 public: | 277 public: |
278 static const int kInvalidAssignment = 0x7fffffff; | 278 static const int kInvalidAssignment = 0x7fffffff; |
279 | 279 |
280 explicit LiveRange(int id); | 280 LiveRange(int id, Zone* zone); |
281 | 281 |
282 UseInterval* first_interval() const { return first_interval_; } | 282 UseInterval* first_interval() const { return first_interval_; } |
283 UsePosition* first_pos() const { return first_pos_; } | 283 UsePosition* first_pos() const { return first_pos_; } |
284 LiveRange* parent() const { return parent_; } | 284 LiveRange* parent() const { return parent_; } |
285 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } | 285 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } |
286 LiveRange* next() const { return next_; } | 286 LiveRange* next() const { return next_; } |
287 bool IsChild() const { return parent() != NULL; } | 287 bool IsChild() const { return parent() != NULL; } |
288 int id() const { return id_; } | 288 int id() const { return id_; } |
289 bool IsFixed() const { return id_ < 0; } | 289 bool IsFixed() const { return id_ < 0; } |
290 bool IsEmpty() const { return first_interval() == NULL; } | 290 bool IsEmpty() const { return first_interval() == NULL; } |
291 LOperand* CreateAssignedOperand(); | 291 LOperand* CreateAssignedOperand(Zone* zone); |
292 int assigned_register() const { return assigned_register_; } | 292 int assigned_register() const { return assigned_register_; } |
293 int spill_start_index() const { return spill_start_index_; } | 293 int spill_start_index() const { return spill_start_index_; } |
294 void set_assigned_register(int reg, RegisterKind register_kind); | 294 void set_assigned_register(int reg, |
295 void MakeSpilled(); | 295 RegisterKind register_kind, |
| 296 Zone* zone); |
| 297 void MakeSpilled(Zone* zone); |
296 | 298 |
297 // Returns use position in this live range that follows both start | 299 // Returns use position in this live range that follows both start |
298 // and last processed use position. | 300 // and last processed use position. |
299 // Modifies internal state of live range! | 301 // Modifies internal state of live range! |
300 UsePosition* NextUsePosition(LifetimePosition start); | 302 UsePosition* NextUsePosition(LifetimePosition start); |
301 | 303 |
302 // Returns use position for which register is required in this live | 304 // Returns use position for which register is required in this live |
303 // range and which follows both start and last processed use position | 305 // range and which follows both start and last processed use position |
304 // Modifies internal state of live range! | 306 // Modifies internal state of live range! |
305 UsePosition* NextRegisterPosition(LifetimePosition start); | 307 UsePosition* NextRegisterPosition(LifetimePosition start); |
306 | 308 |
307 // Returns use position for which register is beneficial in this live | 309 // Returns use position for which register is beneficial in this live |
308 // range and which follows both start and last processed use position | 310 // range and which follows both start and last processed use position |
309 // Modifies internal state of live range! | 311 // Modifies internal state of live range! |
310 UsePosition* NextUsePositionRegisterIsBeneficial(LifetimePosition start); | 312 UsePosition* NextUsePositionRegisterIsBeneficial(LifetimePosition start); |
311 | 313 |
312 // Can this live range be spilled at this position. | 314 // Can this live range be spilled at this position. |
313 bool CanBeSpilled(LifetimePosition pos); | 315 bool CanBeSpilled(LifetimePosition pos); |
314 | 316 |
315 // Split this live range at the given position which must follow the start of | 317 // Split this live range at the given position which must follow the start of |
316 // the range. | 318 // the range. |
317 // All uses following the given position will be moved from this | 319 // All uses following the given position will be moved from this |
318 // live range to the result live range. | 320 // live range to the result live range. |
319 void SplitAt(LifetimePosition position, LiveRange* result); | 321 void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone); |
320 | 322 |
321 bool IsDouble() const { return is_double_; } | 323 bool IsDouble() const { return is_double_; } |
322 bool HasRegisterAssigned() const { | 324 bool HasRegisterAssigned() const { |
323 return assigned_register_ != kInvalidAssignment; | 325 return assigned_register_ != kInvalidAssignment; |
324 } | 326 } |
325 bool IsSpilled() const { return spilled_; } | 327 bool IsSpilled() const { return spilled_; } |
326 UsePosition* FirstPosWithHint() const; | 328 UsePosition* FirstPosWithHint() const; |
327 | 329 |
328 LOperand* FirstHint() const { | 330 LOperand* FirstHint() const { |
329 UsePosition* pos = FirstPosWithHint(); | 331 UsePosition* pos = FirstPosWithHint(); |
(...skipping 18 matching lines...) Expand all Loading... |
348 void SetSpillStartIndex(int start) { | 350 void SetSpillStartIndex(int start) { |
349 spill_start_index_ = Min(start, spill_start_index_); | 351 spill_start_index_ = Min(start, spill_start_index_); |
350 } | 352 } |
351 | 353 |
352 bool ShouldBeAllocatedBefore(const LiveRange* other) const; | 354 bool ShouldBeAllocatedBefore(const LiveRange* other) const; |
353 bool CanCover(LifetimePosition position) const; | 355 bool CanCover(LifetimePosition position) const; |
354 bool Covers(LifetimePosition position); | 356 bool Covers(LifetimePosition position); |
355 LifetimePosition FirstIntersection(LiveRange* other); | 357 LifetimePosition FirstIntersection(LiveRange* other); |
356 | 358 |
357 // Add a new interval or a new use position to this live range. | 359 // Add a new interval or a new use position to this live range. |
358 void EnsureInterval(LifetimePosition start, LifetimePosition end); | 360 void EnsureInterval(LifetimePosition start, |
359 void AddUseInterval(LifetimePosition start, LifetimePosition end); | 361 LifetimePosition end, |
360 UsePosition* AddUsePosition(LifetimePosition pos, LOperand* operand); | 362 Zone* zone); |
| 363 void AddUseInterval(LifetimePosition start, |
| 364 LifetimePosition end, |
| 365 Zone* zone); |
| 366 UsePosition* AddUsePosition(LifetimePosition pos, |
| 367 LOperand* operand, |
| 368 Zone* zone); |
361 | 369 |
362 // Shorten the most recently added interval by setting a new start. | 370 // Shorten the most recently added interval by setting a new start. |
363 void ShortenTo(LifetimePosition start); | 371 void ShortenTo(LifetimePosition start); |
364 | 372 |
365 #ifdef DEBUG | 373 #ifdef DEBUG |
366 // True if target overlaps an existing interval. | 374 // True if target overlaps an existing interval. |
367 bool HasOverlap(UseInterval* target) const; | 375 bool HasOverlap(UseInterval* target) const; |
368 void Verify() const; | 376 void Verify() const; |
369 #endif | 377 #endif |
370 | 378 |
371 private: | 379 private: |
372 void ConvertOperands(); | 380 void ConvertOperands(Zone* zone); |
373 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; | 381 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; |
374 void AdvanceLastProcessedMarker(UseInterval* to_start_of, | 382 void AdvanceLastProcessedMarker(UseInterval* to_start_of, |
375 LifetimePosition but_not_past) const; | 383 LifetimePosition but_not_past) const; |
376 | 384 |
377 int id_; | 385 int id_; |
378 bool spilled_; | 386 bool spilled_; |
379 bool is_double_; | 387 bool is_double_; |
380 int assigned_register_; | 388 int assigned_register_; |
381 UseInterval* last_interval_; | 389 UseInterval* last_interval_; |
382 UseInterval* first_interval_; | 390 UseInterval* first_interval_; |
(...skipping 10 matching lines...) Expand all Loading... |
393 | 401 |
394 class GrowableBitVector BASE_EMBEDDED { | 402 class GrowableBitVector BASE_EMBEDDED { |
395 public: | 403 public: |
396 GrowableBitVector() : bits_(NULL) { } | 404 GrowableBitVector() : bits_(NULL) { } |
397 | 405 |
398 bool Contains(int value) const { | 406 bool Contains(int value) const { |
399 if (!InBitsRange(value)) return false; | 407 if (!InBitsRange(value)) return false; |
400 return bits_->Contains(value); | 408 return bits_->Contains(value); |
401 } | 409 } |
402 | 410 |
403 void Add(int value) { | 411 void Add(int value, Zone* zone) { |
404 EnsureCapacity(value); | 412 EnsureCapacity(value, zone); |
405 bits_->Add(value); | 413 bits_->Add(value); |
406 } | 414 } |
407 | 415 |
408 private: | 416 private: |
409 static const int kInitialLength = 1024; | 417 static const int kInitialLength = 1024; |
410 | 418 |
411 bool InBitsRange(int value) const { | 419 bool InBitsRange(int value) const { |
412 return bits_ != NULL && bits_->length() > value; | 420 return bits_ != NULL && bits_->length() > value; |
413 } | 421 } |
414 | 422 |
415 void EnsureCapacity(int value) { | 423 void EnsureCapacity(int value, Zone* zone) { |
416 if (InBitsRange(value)) return; | 424 if (InBitsRange(value)) return; |
417 int new_length = bits_ == NULL ? kInitialLength : bits_->length(); | 425 int new_length = bits_ == NULL ? kInitialLength : bits_->length(); |
418 while (new_length <= value) new_length *= 2; | 426 while (new_length <= value) new_length *= 2; |
419 BitVector* new_bits = new BitVector(new_length); | 427 BitVector* new_bits = new(zone) BitVector(new_length); |
420 if (bits_ != NULL) new_bits->CopyFrom(*bits_); | 428 if (bits_ != NULL) new_bits->CopyFrom(*bits_); |
421 bits_ = new_bits; | 429 bits_ = new_bits; |
422 } | 430 } |
423 | 431 |
424 BitVector* bits_; | 432 BitVector* bits_; |
425 }; | 433 }; |
426 | 434 |
427 | 435 |
428 class LAllocator BASE_EMBEDDED { | 436 class LAllocator BASE_EMBEDDED { |
429 public: | 437 public: |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 LGap* GetLastGap(HBasicBlock* block); | 588 LGap* GetLastGap(HBasicBlock* block); |
581 | 589 |
582 const char* RegisterName(int allocation_index); | 590 const char* RegisterName(int allocation_index); |
583 | 591 |
584 inline bool IsGapAt(int index); | 592 inline bool IsGapAt(int index); |
585 | 593 |
586 inline LInstruction* InstructionAt(int index); | 594 inline LInstruction* InstructionAt(int index); |
587 | 595 |
588 inline LGap* GapAt(int index); | 596 inline LGap* GapAt(int index); |
589 | 597 |
| 598 Zone* zone_; |
| 599 |
590 LChunk* chunk_; | 600 LChunk* chunk_; |
591 | 601 |
592 // Indicates success or failure during register allocation. | |
593 bool allocation_ok_; | |
594 | |
595 // During liveness analysis keep a mapping from block id to live_in sets | 602 // During liveness analysis keep a mapping from block id to live_in sets |
596 // for blocks already analyzed. | 603 // for blocks already analyzed. |
597 ZoneList<BitVector*> live_in_sets_; | 604 ZoneList<BitVector*> live_in_sets_; |
598 | 605 |
599 // Liveness analysis results. | 606 // Liveness analysis results. |
600 ZoneList<LiveRange*> live_ranges_; | 607 ZoneList<LiveRange*> live_ranges_; |
601 | 608 |
602 // Lists of live ranges | 609 // Lists of live ranges |
603 EmbeddedVector<LiveRange*, Register::kNumAllocatableRegisters> | 610 EmbeddedVector<LiveRange*, Register::kNumAllocatableRegisters> |
604 fixed_live_ranges_; | 611 fixed_live_ranges_; |
605 EmbeddedVector<LiveRange*, DoubleRegister::kNumAllocatableRegisters> | 612 EmbeddedVector<LiveRange*, DoubleRegister::kNumAllocatableRegisters> |
606 fixed_double_live_ranges_; | 613 fixed_double_live_ranges_; |
607 ZoneList<LiveRange*> unhandled_live_ranges_; | 614 ZoneList<LiveRange*> unhandled_live_ranges_; |
608 ZoneList<LiveRange*> active_live_ranges_; | 615 ZoneList<LiveRange*> active_live_ranges_; |
609 ZoneList<LiveRange*> inactive_live_ranges_; | 616 ZoneList<LiveRange*> inactive_live_ranges_; |
610 ZoneList<LiveRange*> reusable_slots_; | 617 ZoneList<LiveRange*> reusable_slots_; |
611 | 618 |
612 // Next virtual register number to be assigned to temporaries. | 619 // Next virtual register number to be assigned to temporaries. |
613 int next_virtual_register_; | 620 int next_virtual_register_; |
614 int first_artificial_register_; | 621 int first_artificial_register_; |
615 GrowableBitVector double_artificial_registers_; | 622 GrowableBitVector double_artificial_registers_; |
616 | 623 |
617 RegisterKind mode_; | 624 RegisterKind mode_; |
618 int num_registers_; | 625 int num_registers_; |
619 | 626 |
620 HGraph* graph_; | 627 HGraph* graph_; |
621 | 628 |
622 bool has_osr_entry_; | 629 bool has_osr_entry_; |
623 | 630 |
| 631 // Indicates success or failure during register allocation. |
| 632 bool allocation_ok_; |
| 633 |
624 DISALLOW_COPY_AND_ASSIGN(LAllocator); | 634 DISALLOW_COPY_AND_ASSIGN(LAllocator); |
625 }; | 635 }; |
626 | 636 |
627 | 637 |
628 } } // namespace v8::internal | 638 } } // namespace v8::internal |
629 | 639 |
630 #endif // V8_LITHIUM_ALLOCATOR_H_ | 640 #endif // V8_LITHIUM_ALLOCATOR_H_ |
OLD | NEW |