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

Side by Side Diff: src/lithium-allocator.h

Issue 11575030: For the values defined in the loop and spilled outside sink spill store out of the loop down to loo… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: address comments Created 7 years, 10 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
« no previous file with comments | « src/hydrogen.cc ('k') | src/lithium-allocator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(Zone* zone); 291 LOperand* CreateAssignedOperand(Zone* zone);
292 int assigned_register() const { return assigned_register_; } 292 int assigned_register() const { return assigned_register_; }
293
293 int spill_start_index() const { return spill_start_index_; } 294 int spill_start_index() const { return spill_start_index_; }
295 void set_spill_start_index(int start) { spill_start_index_ = start; }
296
294 void set_assigned_register(int reg, 297 void set_assigned_register(int reg,
295 RegisterKind register_kind, 298 RegisterKind register_kind,
296 Zone* zone); 299 Zone* zone);
297 void MakeSpilled(Zone* zone); 300 void MakeSpilled(Zone* zone);
298 301
299 // Returns use position in this live range that follows both start 302 // Returns use position in this live range that follows both start
300 // and last processed use position. 303 // and last processed use position.
301 // Modifies internal state of live range! 304 // Modifies internal state of live range!
302 UsePosition* NextUsePosition(LifetimePosition start); 305 UsePosition* NextUsePosition(LifetimePosition start);
303 306
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 343
341 LifetimePosition End() const { 344 LifetimePosition End() const {
342 ASSERT(!IsEmpty()); 345 ASSERT(!IsEmpty());
343 return last_interval_->end(); 346 return last_interval_->end();
344 } 347 }
345 348
346 bool HasAllocatedSpillOperand() const; 349 bool HasAllocatedSpillOperand() const;
347 LOperand* GetSpillOperand() const { return spill_operand_; } 350 LOperand* GetSpillOperand() const { return spill_operand_; }
348 void SetSpillOperand(LOperand* operand); 351 void SetSpillOperand(LOperand* operand);
349 352
350 void SetSpillStartIndex(int start) {
351 spill_start_index_ = Min(start, spill_start_index_);
352 }
353
354 bool ShouldBeAllocatedBefore(const LiveRange* other) const; 353 bool ShouldBeAllocatedBefore(const LiveRange* other) const;
355 bool CanCover(LifetimePosition position) const; 354 bool CanCover(LifetimePosition position) const;
356 bool Covers(LifetimePosition position); 355 bool Covers(LifetimePosition position);
357 LifetimePosition FirstIntersection(LiveRange* other); 356 LifetimePosition FirstIntersection(LiveRange* other);
358 357
359 // Add a new interval or a new use position to this live range. 358 // Add a new interval or a new use position to this live range.
360 void EnsureInterval(LifetimePosition start, 359 void EnsureInterval(LifetimePosition start,
361 LifetimePosition end, 360 LifetimePosition end,
362 Zone* zone); 361 Zone* zone);
363 void AddUseInterval(LifetimePosition start, 362 void AddUseInterval(LifetimePosition start,
364 LifetimePosition end, 363 LifetimePosition end,
365 Zone* zone); 364 Zone* zone);
366 UsePosition* AddUsePosition(LifetimePosition pos, 365 UsePosition* AddUsePosition(LifetimePosition pos,
367 LOperand* operand, 366 LOperand* operand,
368 Zone* zone); 367 Zone* zone);
369 368
370 // Shorten the most recently added interval by setting a new start. 369 // Shorten the most recently added interval by setting a new start.
371 void ShortenTo(LifetimePosition start); 370 void ShortenTo(LifetimePosition start);
372 371
373 #ifdef DEBUG 372 #ifdef DEBUG
374 // True if target overlaps an existing interval. 373 // True if target overlaps an existing interval.
375 bool HasOverlap(UseInterval* target) const; 374 bool HasOverlap(UseInterval* target) const;
376 void Verify() const; 375 void Verify() const;
377 #endif 376 #endif
378 377
378 static const intptr_t kDisabledSpillStoreSinkingMarker = -1;
379
380 LOperand* spill_source() { return spill_source_; }
381 void set_spill_source(LOperand* spill_source) {
382 spill_source_ = spill_source;
383 }
384
385 bool HasPendingSpillStore() {
386 return (spill_source() !=
387 reinterpret_cast<LOperand*>(kDisabledSpillStoreSinkingMarker)) &&
388 (spill_source() != NULL);
389 }
390
391 void DisableSpillStoreSinking() {
392 set_spill_source(
393 reinterpret_cast<LOperand*>(kDisabledSpillStoreSinkingMarker));
394 }
395
379 private: 396 private:
380 void ConvertOperands(Zone* zone); 397 void ConvertOperands(Zone* zone);
381 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; 398 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
382 void AdvanceLastProcessedMarker(UseInterval* to_start_of, 399 void AdvanceLastProcessedMarker(UseInterval* to_start_of,
383 LifetimePosition but_not_past) const; 400 LifetimePosition but_not_past) const;
384 401
385 int id_; 402 int id_;
386 bool spilled_; 403 bool spilled_;
387 bool is_double_; 404 bool is_double_;
388 int assigned_register_; 405 int assigned_register_;
389 UseInterval* last_interval_; 406 UseInterval* last_interval_;
390 UseInterval* first_interval_; 407 UseInterval* first_interval_;
391 UsePosition* first_pos_; 408 UsePosition* first_pos_;
392 LiveRange* parent_; 409 LiveRange* parent_;
393 LiveRange* next_; 410 LiveRange* next_;
394 // This is used as a cache, it doesn't affect correctness. 411 // This is used as a cache, it doesn't affect correctness.
395 mutable UseInterval* current_interval_; 412 mutable UseInterval* current_interval_;
396 UsePosition* last_processed_use_; 413 UsePosition* last_processed_use_;
397 LOperand* spill_operand_; 414 LOperand* spill_operand_;
398 int spill_start_index_; 415 int spill_start_index_;
416 LOperand* spill_source_;
399 }; 417 };
400 418
401 419
402 class GrowableBitVector BASE_EMBEDDED { 420 class GrowableBitVector BASE_EMBEDDED {
403 public: 421 public:
404 GrowableBitVector() : bits_(NULL) { } 422 GrowableBitVector() : bits_(NULL) { }
405 423
406 bool Contains(int value) const { 424 bool Contains(int value) const {
407 if (!InBitsRange(value)) return false; 425 if (!InBitsRange(value)) return false;
408 return bits_->Contains(value); 426 return bits_->Contains(value);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 void SpillAfter(LiveRange* range, LifetimePosition pos); 575 void SpillAfter(LiveRange* range, LifetimePosition pos);
558 576
559 // Spill the given life range after position start and up to position end. 577 // Spill the given life range after position start and up to position end.
560 void SpillBetween(LiveRange* range, 578 void SpillBetween(LiveRange* range,
561 LifetimePosition start, 579 LifetimePosition start,
562 LifetimePosition end); 580 LifetimePosition end);
563 581
564 void SplitAndSpillIntersecting(LiveRange* range); 582 void SplitAndSpillIntersecting(LiveRange* range);
565 583
566 void Spill(LiveRange* range); 584 void Spill(LiveRange* range);
585
586 // Emit spill store for the given range that moves value from the register
587 // where it was produced (spill source) to the allocated spill slot.
588 void EmitSpillStore(LiveRange* range);
589 void EmitSpillStore(int pos, LOperand* source, LOperand* spill);
590
591 // Try sink spill store for the given range down to the beginning of the
592 // given block. This is done only if the block dominates all spilled split
593 // siblings.
594 bool TrySinkSpillStoreTo(LiveRange* range, HBasicBlock* block);
595
567 bool IsBlockBoundary(LifetimePosition pos); 596 bool IsBlockBoundary(LifetimePosition pos);
568 597
569 // Helper methods for resolving control flow. 598 // Helper methods for resolving control flow.
570 void ResolveControlFlow(LiveRange* range, 599 void ResolveControlFlow(LiveRange* range,
571 HBasicBlock* block, 600 HBasicBlock* block,
572 HBasicBlock* pred); 601 HBasicBlock* pred);
573 602
603 // Emit all pending spill stores for ranges that have spilled siblings sinking
604 // stores down to loop exits whenever possible.
605 void SinkSpillStores();
606
574 // Return parallel move that should be used to connect ranges split at the 607 // Return parallel move that should be used to connect ranges split at the
575 // given position. 608 // given position.
576 LParallelMove* GetConnectingParallelMove(LifetimePosition pos); 609 LParallelMove* GetConnectingParallelMove(LifetimePosition pos);
577 610
578 // Return the block which contains give lifetime position. 611 // Return the block which contains give lifetime position.
579 HBasicBlock* GetBlock(LifetimePosition pos); 612 HBasicBlock* GetBlock(LifetimePosition pos);
580 613
581 // Helper methods for the fixed registers. 614 // Helper methods for the fixed registers.
582 int RegisterCount() const; 615 int RegisterCount() const;
583 static int FixedLiveRangeID(int index) { return -index - 1; } 616 static int FixedLiveRangeID(int index) { return -index - 1; }
(...skipping 26 matching lines...) Expand all
610 // Lists of live ranges 643 // Lists of live ranges
611 EmbeddedVector<LiveRange*, Register::kNumAllocatableRegisters> 644 EmbeddedVector<LiveRange*, Register::kNumAllocatableRegisters>
612 fixed_live_ranges_; 645 fixed_live_ranges_;
613 EmbeddedVector<LiveRange*, DoubleRegister::kNumAllocatableRegisters> 646 EmbeddedVector<LiveRange*, DoubleRegister::kNumAllocatableRegisters>
614 fixed_double_live_ranges_; 647 fixed_double_live_ranges_;
615 ZoneList<LiveRange*> unhandled_live_ranges_; 648 ZoneList<LiveRange*> unhandled_live_ranges_;
616 ZoneList<LiveRange*> active_live_ranges_; 649 ZoneList<LiveRange*> active_live_ranges_;
617 ZoneList<LiveRange*> inactive_live_ranges_; 650 ZoneList<LiveRange*> inactive_live_ranges_;
618 ZoneList<LiveRange*> reusable_slots_; 651 ZoneList<LiveRange*> reusable_slots_;
619 652
653 // List of live ranges that were spilled but did not have
654 // spill store emitted eagerly.
655 ZoneList<LiveRange*> pending_spilled_;
656
620 // Next virtual register number to be assigned to temporaries. 657 // Next virtual register number to be assigned to temporaries.
621 int next_virtual_register_; 658 int next_virtual_register_;
622 int first_artificial_register_; 659 int first_artificial_register_;
623 GrowableBitVector double_artificial_registers_; 660 GrowableBitVector double_artificial_registers_;
624 661
625 RegisterKind mode_; 662 RegisterKind mode_;
626 int num_registers_; 663 int num_registers_;
627 664
628 HGraph* graph_; 665 HGraph* graph_;
629 666
630 bool has_osr_entry_; 667 bool has_osr_entry_;
631 668
632 // Indicates success or failure during register allocation. 669 // Indicates success or failure during register allocation.
633 bool allocation_ok_; 670 bool allocation_ok_;
634 671
635 DISALLOW_COPY_AND_ASSIGN(LAllocator); 672 DISALLOW_COPY_AND_ASSIGN(LAllocator);
636 }; 673 };
637 674
638 675
639 } } // namespace v8::internal 676 } } // namespace v8::internal
640 677
641 #endif // V8_LITHIUM_ALLOCATOR_H_ 678 #endif // V8_LITHIUM_ALLOCATOR_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/lithium-allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698