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

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

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes 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
« no previous file with comments | « src/lithium-allocator.h ('k') | src/lithium-allocator-inl.h » ('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 // 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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/hydrogen.h" 7 #include "src/hydrogen.h"
8 #include "src/lithium-inl.h" 8 #include "src/lithium-inl.h"
9 #include "src/lithium-allocator-inl.h" 9 #include "src/lithium-allocator-inl.h"
10 #include "src/string-stream.h" 10 #include "src/string-stream.h"
(...skipping 19 matching lines...) Expand all
30 pos_(pos), 30 pos_(pos),
31 next_(NULL), 31 next_(NULL),
32 requires_reg_(false), 32 requires_reg_(false),
33 register_beneficial_(true) { 33 register_beneficial_(true) {
34 if (operand_ != NULL && operand_->IsUnallocated()) { 34 if (operand_ != NULL && operand_->IsUnallocated()) {
35 LUnallocated* unalloc = LUnallocated::cast(operand_); 35 LUnallocated* unalloc = LUnallocated::cast(operand_);
36 requires_reg_ = unalloc->HasRegisterPolicy() || 36 requires_reg_ = unalloc->HasRegisterPolicy() ||
37 unalloc->HasDoubleRegisterPolicy(); 37 unalloc->HasDoubleRegisterPolicy();
38 register_beneficial_ = !unalloc->HasAnyPolicy(); 38 register_beneficial_ = !unalloc->HasAnyPolicy();
39 } 39 }
40 ASSERT(pos_.IsValid()); 40 DCHECK(pos_.IsValid());
41 } 41 }
42 42
43 43
44 bool UsePosition::HasHint() const { 44 bool UsePosition::HasHint() const {
45 return hint_ != NULL && !hint_->IsUnallocated(); 45 return hint_ != NULL && !hint_->IsUnallocated();
46 } 46 }
47 47
48 48
49 bool UsePosition::RequiresRegister() const { 49 bool UsePosition::RequiresRegister() const {
50 return requires_reg_; 50 return requires_reg_;
51 } 51 }
52 52
53 53
54 bool UsePosition::RegisterIsBeneficial() const { 54 bool UsePosition::RegisterIsBeneficial() const {
55 return register_beneficial_; 55 return register_beneficial_;
56 } 56 }
57 57
58 58
59 void UseInterval::SplitAt(LifetimePosition pos, Zone* zone) { 59 void UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
60 ASSERT(Contains(pos) && pos.Value() != start().Value()); 60 DCHECK(Contains(pos) && pos.Value() != start().Value());
61 UseInterval* after = new(zone) UseInterval(pos, end_); 61 UseInterval* after = new(zone) UseInterval(pos, end_);
62 after->next_ = next_; 62 after->next_ = next_;
63 next_ = after; 63 next_ = after;
64 end_ = pos; 64 end_ = pos;
65 } 65 }
66 66
67 67
68 #ifdef DEBUG 68 #ifdef DEBUG
69 69
70 70
71 void LiveRange::Verify() const { 71 void LiveRange::Verify() const {
72 UsePosition* cur = first_pos_; 72 UsePosition* cur = first_pos_;
73 while (cur != NULL) { 73 while (cur != NULL) {
74 ASSERT(Start().Value() <= cur->pos().Value() && 74 DCHECK(Start().Value() <= cur->pos().Value() &&
75 cur->pos().Value() <= End().Value()); 75 cur->pos().Value() <= End().Value());
76 cur = cur->next(); 76 cur = cur->next();
77 } 77 }
78 } 78 }
79 79
80 80
81 bool LiveRange::HasOverlap(UseInterval* target) const { 81 bool LiveRange::HasOverlap(UseInterval* target) const {
82 UseInterval* current_interval = first_interval_; 82 UseInterval* current_interval = first_interval_;
83 while (current_interval != NULL) { 83 while (current_interval != NULL) {
84 // Intervals overlap if the start of one is contained in the other. 84 // Intervals overlap if the start of one is contained in the other.
(...skipping 21 matching lines...) Expand all
106 parent_(NULL), 106 parent_(NULL),
107 next_(NULL), 107 next_(NULL),
108 current_interval_(NULL), 108 current_interval_(NULL),
109 last_processed_use_(NULL), 109 last_processed_use_(NULL),
110 current_hint_operand_(NULL), 110 current_hint_operand_(NULL),
111 spill_operand_(new(zone) LOperand()), 111 spill_operand_(new(zone) LOperand()),
112 spill_start_index_(kMaxInt) { } 112 spill_start_index_(kMaxInt) { }
113 113
114 114
115 void LiveRange::set_assigned_register(int reg, Zone* zone) { 115 void LiveRange::set_assigned_register(int reg, Zone* zone) {
116 ASSERT(!HasRegisterAssigned() && !IsSpilled()); 116 DCHECK(!HasRegisterAssigned() && !IsSpilled());
117 assigned_register_ = reg; 117 assigned_register_ = reg;
118 ConvertOperands(zone); 118 ConvertOperands(zone);
119 } 119 }
120 120
121 121
122 void LiveRange::MakeSpilled(Zone* zone) { 122 void LiveRange::MakeSpilled(Zone* zone) {
123 ASSERT(!IsSpilled()); 123 DCHECK(!IsSpilled());
124 ASSERT(TopLevel()->HasAllocatedSpillOperand()); 124 DCHECK(TopLevel()->HasAllocatedSpillOperand());
125 spilled_ = true; 125 spilled_ = true;
126 assigned_register_ = kInvalidAssignment; 126 assigned_register_ = kInvalidAssignment;
127 ConvertOperands(zone); 127 ConvertOperands(zone);
128 } 128 }
129 129
130 130
131 bool LiveRange::HasAllocatedSpillOperand() const { 131 bool LiveRange::HasAllocatedSpillOperand() const {
132 ASSERT(spill_operand_ != NULL); 132 DCHECK(spill_operand_ != NULL);
133 return !spill_operand_->IsIgnored(); 133 return !spill_operand_->IsIgnored();
134 } 134 }
135 135
136 136
137 void LiveRange::SetSpillOperand(LOperand* operand) { 137 void LiveRange::SetSpillOperand(LOperand* operand) {
138 ASSERT(!operand->IsUnallocated()); 138 DCHECK(!operand->IsUnallocated());
139 ASSERT(spill_operand_ != NULL); 139 DCHECK(spill_operand_ != NULL);
140 ASSERT(spill_operand_->IsIgnored()); 140 DCHECK(spill_operand_->IsIgnored());
141 spill_operand_->ConvertTo(operand->kind(), operand->index()); 141 spill_operand_->ConvertTo(operand->kind(), operand->index());
142 } 142 }
143 143
144 144
145 UsePosition* LiveRange::NextUsePosition(LifetimePosition start) { 145 UsePosition* LiveRange::NextUsePosition(LifetimePosition start) {
146 UsePosition* use_pos = last_processed_use_; 146 UsePosition* use_pos = last_processed_use_;
147 if (use_pos == NULL) use_pos = first_pos(); 147 if (use_pos == NULL) use_pos = first_pos();
148 while (use_pos != NULL && use_pos->pos().Value() < start.Value()) { 148 while (use_pos != NULL && use_pos->pos().Value() < start.Value()) {
149 use_pos = use_pos->next(); 149 use_pos = use_pos->next();
150 } 150 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 UsePosition* use_pos = NextRegisterPosition(pos); 190 UsePosition* use_pos = NextRegisterPosition(pos);
191 if (use_pos == NULL) return true; 191 if (use_pos == NULL) return true;
192 return 192 return
193 use_pos->pos().Value() > pos.NextInstruction().InstructionEnd().Value(); 193 use_pos->pos().Value() > pos.NextInstruction().InstructionEnd().Value();
194 } 194 }
195 195
196 196
197 LOperand* LiveRange::CreateAssignedOperand(Zone* zone) { 197 LOperand* LiveRange::CreateAssignedOperand(Zone* zone) {
198 LOperand* op = NULL; 198 LOperand* op = NULL;
199 if (HasRegisterAssigned()) { 199 if (HasRegisterAssigned()) {
200 ASSERT(!IsSpilled()); 200 DCHECK(!IsSpilled());
201 switch (Kind()) { 201 switch (Kind()) {
202 case GENERAL_REGISTERS: 202 case GENERAL_REGISTERS:
203 op = LRegister::Create(assigned_register(), zone); 203 op = LRegister::Create(assigned_register(), zone);
204 break; 204 break;
205 case DOUBLE_REGISTERS: 205 case DOUBLE_REGISTERS:
206 op = LDoubleRegister::Create(assigned_register(), zone); 206 op = LDoubleRegister::Create(assigned_register(), zone);
207 break; 207 break;
208 default: 208 default:
209 UNREACHABLE(); 209 UNREACHABLE();
210 } 210 }
211 } else if (IsSpilled()) { 211 } else if (IsSpilled()) {
212 ASSERT(!HasRegisterAssigned()); 212 DCHECK(!HasRegisterAssigned());
213 op = TopLevel()->GetSpillOperand(); 213 op = TopLevel()->GetSpillOperand();
214 ASSERT(!op->IsUnallocated()); 214 DCHECK(!op->IsUnallocated());
215 } else { 215 } else {
216 LUnallocated* unalloc = new(zone) LUnallocated(LUnallocated::NONE); 216 LUnallocated* unalloc = new(zone) LUnallocated(LUnallocated::NONE);
217 unalloc->set_virtual_register(id_); 217 unalloc->set_virtual_register(id_);
218 op = unalloc; 218 op = unalloc;
219 } 219 }
220 return op; 220 return op;
221 } 221 }
222 222
223 223
224 UseInterval* LiveRange::FirstSearchIntervalForPosition( 224 UseInterval* LiveRange::FirstSearchIntervalForPosition(
(...skipping 16 matching lines...) Expand all
241 : current_interval_->start(); 241 : current_interval_->start();
242 if (to_start_of->start().Value() > start.Value()) { 242 if (to_start_of->start().Value() > start.Value()) {
243 current_interval_ = to_start_of; 243 current_interval_ = to_start_of;
244 } 244 }
245 } 245 }
246 246
247 247
248 void LiveRange::SplitAt(LifetimePosition position, 248 void LiveRange::SplitAt(LifetimePosition position,
249 LiveRange* result, 249 LiveRange* result,
250 Zone* zone) { 250 Zone* zone) {
251 ASSERT(Start().Value() < position.Value()); 251 DCHECK(Start().Value() < position.Value());
252 ASSERT(result->IsEmpty()); 252 DCHECK(result->IsEmpty());
253 // Find the last interval that ends before the position. If the 253 // Find the last interval that ends before the position. If the
254 // position is contained in one of the intervals in the chain, we 254 // position is contained in one of the intervals in the chain, we
255 // split that interval and use the first part. 255 // split that interval and use the first part.
256 UseInterval* current = FirstSearchIntervalForPosition(position); 256 UseInterval* current = FirstSearchIntervalForPosition(position);
257 257
258 // If the split position coincides with the beginning of a use interval 258 // If the split position coincides with the beginning of a use interval
259 // we need to split use positons in a special way. 259 // we need to split use positons in a special way.
260 bool split_at_start = false; 260 bool split_at_start = false;
261 261
262 if (current->start().Value() == position.Value()) { 262 if (current->start().Value() == position.Value()) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 UsePosition* other_pos = other->first_pos(); 346 UsePosition* other_pos = other->first_pos();
347 if (other_pos == NULL) return true; 347 if (other_pos == NULL) return true;
348 return pos->pos().Value() < other_pos->pos().Value(); 348 return pos->pos().Value() < other_pos->pos().Value();
349 } 349 }
350 return start.Value() < other_start.Value(); 350 return start.Value() < other_start.Value();
351 } 351 }
352 352
353 353
354 void LiveRange::ShortenTo(LifetimePosition start) { 354 void LiveRange::ShortenTo(LifetimePosition start) {
355 LAllocator::TraceAlloc("Shorten live range %d to [%d\n", id_, start.Value()); 355 LAllocator::TraceAlloc("Shorten live range %d to [%d\n", id_, start.Value());
356 ASSERT(first_interval_ != NULL); 356 DCHECK(first_interval_ != NULL);
357 ASSERT(first_interval_->start().Value() <= start.Value()); 357 DCHECK(first_interval_->start().Value() <= start.Value());
358 ASSERT(start.Value() < first_interval_->end().Value()); 358 DCHECK(start.Value() < first_interval_->end().Value());
359 first_interval_->set_start(start); 359 first_interval_->set_start(start);
360 } 360 }
361 361
362 362
363 void LiveRange::EnsureInterval(LifetimePosition start, 363 void LiveRange::EnsureInterval(LifetimePosition start,
364 LifetimePosition end, 364 LifetimePosition end,
365 Zone* zone) { 365 Zone* zone) {
366 LAllocator::TraceAlloc("Ensure live range %d in interval [%d %d[\n", 366 LAllocator::TraceAlloc("Ensure live range %d in interval [%d %d[\n",
367 id_, 367 id_,
368 start.Value(), 368 start.Value(),
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 if (end.Value() == first_interval_->start().Value()) { 400 if (end.Value() == first_interval_->start().Value()) {
401 first_interval_->set_start(start); 401 first_interval_->set_start(start);
402 } else if (end.Value() < first_interval_->start().Value()) { 402 } else if (end.Value() < first_interval_->start().Value()) {
403 UseInterval* interval = new(zone) UseInterval(start, end); 403 UseInterval* interval = new(zone) UseInterval(start, end);
404 interval->set_next(first_interval_); 404 interval->set_next(first_interval_);
405 first_interval_ = interval; 405 first_interval_ = interval;
406 } else { 406 } else {
407 // Order of instruction's processing (see ProcessInstructions) guarantees 407 // Order of instruction's processing (see ProcessInstructions) guarantees
408 // that each new use interval either precedes or intersects with 408 // that each new use interval either precedes or intersects with
409 // last added interval. 409 // last added interval.
410 ASSERT(start.Value() < first_interval_->end().Value()); 410 DCHECK(start.Value() < first_interval_->end().Value());
411 first_interval_->start_ = Min(start, first_interval_->start_); 411 first_interval_->start_ = Min(start, first_interval_->start_);
412 first_interval_->end_ = Max(end, first_interval_->end_); 412 first_interval_->end_ = Max(end, first_interval_->end_);
413 } 413 }
414 } 414 }
415 } 415 }
416 416
417 417
418 void LiveRange::AddUsePosition(LifetimePosition pos, 418 void LiveRange::AddUsePosition(LifetimePosition pos,
419 LOperand* operand, 419 LOperand* operand,
420 LOperand* hint, 420 LOperand* hint,
(...skipping 22 matching lines...) Expand all
443 if (prev_hint == NULL && use_pos->HasHint()) { 443 if (prev_hint == NULL && use_pos->HasHint()) {
444 current_hint_operand_ = hint; 444 current_hint_operand_ = hint;
445 } 445 }
446 } 446 }
447 447
448 448
449 void LiveRange::ConvertOperands(Zone* zone) { 449 void LiveRange::ConvertOperands(Zone* zone) {
450 LOperand* op = CreateAssignedOperand(zone); 450 LOperand* op = CreateAssignedOperand(zone);
451 UsePosition* use_pos = first_pos(); 451 UsePosition* use_pos = first_pos();
452 while (use_pos != NULL) { 452 while (use_pos != NULL) {
453 ASSERT(Start().Value() <= use_pos->pos().Value() && 453 DCHECK(Start().Value() <= use_pos->pos().Value() &&
454 use_pos->pos().Value() <= End().Value()); 454 use_pos->pos().Value() <= End().Value());
455 455
456 if (use_pos->HasOperand()) { 456 if (use_pos->HasOperand()) {
457 ASSERT(op->IsRegister() || op->IsDoubleRegister() || 457 DCHECK(op->IsRegister() || op->IsDoubleRegister() ||
458 !use_pos->RequiresRegister()); 458 !use_pos->RequiresRegister());
459 use_pos->operand()->ConvertTo(op->kind(), op->index()); 459 use_pos->operand()->ConvertTo(op->kind(), op->index());
460 } 460 }
461 use_pos = use_pos->next(); 461 use_pos = use_pos->next();
462 } 462 }
463 } 463 }
464 464
465 465
466 bool LiveRange::CanCover(LifetimePosition position) const { 466 bool LiveRange::CanCover(LifetimePosition position) const {
467 if (IsEmpty()) return false; 467 if (IsEmpty()) return false;
468 return Start().Value() <= position.Value() && 468 return Start().Value() <= position.Value() &&
469 position.Value() < End().Value(); 469 position.Value() < End().Value();
470 } 470 }
471 471
472 472
473 bool LiveRange::Covers(LifetimePosition position) { 473 bool LiveRange::Covers(LifetimePosition position) {
474 if (!CanCover(position)) return false; 474 if (!CanCover(position)) return false;
475 UseInterval* start_search = FirstSearchIntervalForPosition(position); 475 UseInterval* start_search = FirstSearchIntervalForPosition(position);
476 for (UseInterval* interval = start_search; 476 for (UseInterval* interval = start_search;
477 interval != NULL; 477 interval != NULL;
478 interval = interval->next()) { 478 interval = interval->next()) {
479 ASSERT(interval->next() == NULL || 479 DCHECK(interval->next() == NULL ||
480 interval->next()->start().Value() >= interval->start().Value()); 480 interval->next()->start().Value() >= interval->start().Value());
481 AdvanceLastProcessedMarker(interval, position); 481 AdvanceLastProcessedMarker(interval, position);
482 if (interval->Contains(position)) return true; 482 if (interval->Contains(position)) return true;
483 if (interval->start().Value() > position.Value()) return false; 483 if (interval->start().Value() > position.Value()) return false;
484 } 484 }
485 return false; 485 return false;
486 } 486 }
487 487
488 488
489 LifetimePosition LiveRange::FirstIntersection(LiveRange* other) { 489 LifetimePosition LiveRange::FirstIntersection(LiveRange* other) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 587
588 int LAllocator::FixedDoubleLiveRangeID(int index) { 588 int LAllocator::FixedDoubleLiveRangeID(int index) {
589 return -index - 1 - Register::kMaxNumAllocatableRegisters; 589 return -index - 1 - Register::kMaxNumAllocatableRegisters;
590 } 590 }
591 591
592 592
593 LOperand* LAllocator::AllocateFixed(LUnallocated* operand, 593 LOperand* LAllocator::AllocateFixed(LUnallocated* operand,
594 int pos, 594 int pos,
595 bool is_tagged) { 595 bool is_tagged) {
596 TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register()); 596 TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register());
597 ASSERT(operand->HasFixedPolicy()); 597 DCHECK(operand->HasFixedPolicy());
598 if (operand->HasFixedSlotPolicy()) { 598 if (operand->HasFixedSlotPolicy()) {
599 operand->ConvertTo(LOperand::STACK_SLOT, operand->fixed_slot_index()); 599 operand->ConvertTo(LOperand::STACK_SLOT, operand->fixed_slot_index());
600 } else if (operand->HasFixedRegisterPolicy()) { 600 } else if (operand->HasFixedRegisterPolicy()) {
601 int reg_index = operand->fixed_register_index(); 601 int reg_index = operand->fixed_register_index();
602 operand->ConvertTo(LOperand::REGISTER, reg_index); 602 operand->ConvertTo(LOperand::REGISTER, reg_index);
603 } else if (operand->HasFixedDoubleRegisterPolicy()) { 603 } else if (operand->HasFixedDoubleRegisterPolicy()) {
604 int reg_index = operand->fixed_register_index(); 604 int reg_index = operand->fixed_register_index();
605 operand->ConvertTo(LOperand::DOUBLE_REGISTER, reg_index); 605 operand->ConvertTo(LOperand::DOUBLE_REGISTER, reg_index);
606 } else { 606 } else {
607 UNREACHABLE(); 607 UNREACHABLE();
608 } 608 }
609 if (is_tagged) { 609 if (is_tagged) {
610 TraceAlloc("Fixed reg is tagged at %d\n", pos); 610 TraceAlloc("Fixed reg is tagged at %d\n", pos);
611 LInstruction* instr = InstructionAt(pos); 611 LInstruction* instr = InstructionAt(pos);
612 if (instr->HasPointerMap()) { 612 if (instr->HasPointerMap()) {
613 instr->pointer_map()->RecordPointer(operand, chunk()->zone()); 613 instr->pointer_map()->RecordPointer(operand, chunk()->zone());
614 } 614 }
615 } 615 }
616 return operand; 616 return operand;
617 } 617 }
618 618
619 619
620 LiveRange* LAllocator::FixedLiveRangeFor(int index) { 620 LiveRange* LAllocator::FixedLiveRangeFor(int index) {
621 ASSERT(index < Register::kMaxNumAllocatableRegisters); 621 DCHECK(index < Register::kMaxNumAllocatableRegisters);
622 LiveRange* result = fixed_live_ranges_[index]; 622 LiveRange* result = fixed_live_ranges_[index];
623 if (result == NULL) { 623 if (result == NULL) {
624 result = new(zone()) LiveRange(FixedLiveRangeID(index), chunk()->zone()); 624 result = new(zone()) LiveRange(FixedLiveRangeID(index), chunk()->zone());
625 ASSERT(result->IsFixed()); 625 DCHECK(result->IsFixed());
626 result->kind_ = GENERAL_REGISTERS; 626 result->kind_ = GENERAL_REGISTERS;
627 SetLiveRangeAssignedRegister(result, index); 627 SetLiveRangeAssignedRegister(result, index);
628 fixed_live_ranges_[index] = result; 628 fixed_live_ranges_[index] = result;
629 } 629 }
630 return result; 630 return result;
631 } 631 }
632 632
633 633
634 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) { 634 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) {
635 ASSERT(index < DoubleRegister::NumAllocatableRegisters()); 635 DCHECK(index < DoubleRegister::NumAllocatableRegisters());
636 LiveRange* result = fixed_double_live_ranges_[index]; 636 LiveRange* result = fixed_double_live_ranges_[index];
637 if (result == NULL) { 637 if (result == NULL) {
638 result = new(zone()) LiveRange(FixedDoubleLiveRangeID(index), 638 result = new(zone()) LiveRange(FixedDoubleLiveRangeID(index),
639 chunk()->zone()); 639 chunk()->zone());
640 ASSERT(result->IsFixed()); 640 DCHECK(result->IsFixed());
641 result->kind_ = DOUBLE_REGISTERS; 641 result->kind_ = DOUBLE_REGISTERS;
642 SetLiveRangeAssignedRegister(result, index); 642 SetLiveRangeAssignedRegister(result, index);
643 fixed_double_live_ranges_[index] = result; 643 fixed_double_live_ranges_[index] = result;
644 } 644 }
645 return result; 645 return result;
646 } 646 }
647 647
648 648
649 LiveRange* LAllocator::LiveRangeFor(int index) { 649 LiveRange* LAllocator::LiveRangeFor(int index) {
650 if (index >= live_ranges_.length()) { 650 if (index >= live_ranges_.length()) {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 LUnallocated* cur_input = LUnallocated::cast(it.Current()); 820 LUnallocated* cur_input = LUnallocated::cast(it.Current());
821 if (cur_input->HasFixedPolicy()) { 821 if (cur_input->HasFixedPolicy()) {
822 LUnallocated* input_copy = cur_input->CopyUnconstrained( 822 LUnallocated* input_copy = cur_input->CopyUnconstrained(
823 chunk()->zone()); 823 chunk()->zone());
824 bool is_tagged = HasTaggedValue(cur_input->virtual_register()); 824 bool is_tagged = HasTaggedValue(cur_input->virtual_register());
825 AllocateFixed(cur_input, gap_index + 1, is_tagged); 825 AllocateFixed(cur_input, gap_index + 1, is_tagged);
826 AddConstraintsGapMove(gap_index, input_copy, cur_input); 826 AddConstraintsGapMove(gap_index, input_copy, cur_input);
827 } else if (cur_input->HasWritableRegisterPolicy()) { 827 } else if (cur_input->HasWritableRegisterPolicy()) {
828 // The live range of writable input registers always goes until the end 828 // The live range of writable input registers always goes until the end
829 // of the instruction. 829 // of the instruction.
830 ASSERT(!cur_input->IsUsedAtStart()); 830 DCHECK(!cur_input->IsUsedAtStart());
831 831
832 LUnallocated* input_copy = cur_input->CopyUnconstrained( 832 LUnallocated* input_copy = cur_input->CopyUnconstrained(
833 chunk()->zone()); 833 chunk()->zone());
834 int vreg = GetVirtualRegister(); 834 int vreg = GetVirtualRegister();
835 if (!AllocationOk()) return; 835 if (!AllocationOk()) return;
836 cur_input->set_virtual_register(vreg); 836 cur_input->set_virtual_register(vreg);
837 837
838 if (RequiredRegisterKind(input_copy->virtual_register()) == 838 if (RequiredRegisterKind(input_copy->virtual_register()) ==
839 DOUBLE_REGISTERS) { 839 DOUBLE_REGISTERS) {
840 double_artificial_registers_.Add( 840 double_artificial_registers_.Add(
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 } else { 920 } else {
921 Define(curr_position, to, from); 921 Define(curr_position, to, from);
922 } 922 }
923 } 923 }
924 Use(block_start_position, curr_position, from, hint); 924 Use(block_start_position, curr_position, from, hint);
925 if (from->IsUnallocated()) { 925 if (from->IsUnallocated()) {
926 live->Add(LUnallocated::cast(from)->virtual_register()); 926 live->Add(LUnallocated::cast(from)->virtual_register());
927 } 927 }
928 } 928 }
929 } else { 929 } else {
930 ASSERT(!IsGapAt(index)); 930 DCHECK(!IsGapAt(index));
931 LInstruction* instr = InstructionAt(index); 931 LInstruction* instr = InstructionAt(index);
932 932
933 if (instr != NULL) { 933 if (instr != NULL) {
934 LOperand* output = instr->Output(); 934 LOperand* output = instr->Output();
935 if (output != NULL) { 935 if (output != NULL) {
936 if (output->IsUnallocated()) { 936 if (output->IsUnallocated()) {
937 live->Remove(LUnallocated::cast(output)->virtual_register()); 937 live->Remove(LUnallocated::cast(output)->virtual_register());
938 } 938 }
939 Define(curr_position, output, NULL); 939 Define(curr_position, output, NULL);
940 } 940 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 LUnallocated* phi_operand = 1018 LUnallocated* phi_operand =
1019 new(chunk()->zone()) LUnallocated(LUnallocated::NONE); 1019 new(chunk()->zone()) LUnallocated(LUnallocated::NONE);
1020 phi_operand->set_virtual_register(phi->id()); 1020 phi_operand->set_virtual_register(phi->id());
1021 for (int j = 0; j < phi->OperandCount(); ++j) { 1021 for (int j = 0; j < phi->OperandCount(); ++j) {
1022 HValue* op = phi->OperandAt(j); 1022 HValue* op = phi->OperandAt(j);
1023 LOperand* operand = NULL; 1023 LOperand* operand = NULL;
1024 if (op->IsConstant() && op->EmitAtUses()) { 1024 if (op->IsConstant() && op->EmitAtUses()) {
1025 HConstant* constant = HConstant::cast(op); 1025 HConstant* constant = HConstant::cast(op);
1026 operand = chunk_->DefineConstantOperand(constant); 1026 operand = chunk_->DefineConstantOperand(constant);
1027 } else { 1027 } else {
1028 ASSERT(!op->EmitAtUses()); 1028 DCHECK(!op->EmitAtUses());
1029 LUnallocated* unalloc = 1029 LUnallocated* unalloc =
1030 new(chunk()->zone()) LUnallocated(LUnallocated::ANY); 1030 new(chunk()->zone()) LUnallocated(LUnallocated::ANY);
1031 unalloc->set_virtual_register(op->id()); 1031 unalloc->set_virtual_register(op->id());
1032 operand = unalloc; 1032 operand = unalloc;
1033 } 1033 }
1034 HBasicBlock* cur_block = block->predecessors()->at(j); 1034 HBasicBlock* cur_block = block->predecessors()->at(j);
1035 // The gap move must be added without any special processing as in 1035 // The gap move must be added without any special processing as in
1036 // the AddConstraintsGapMove. 1036 // the AddConstraintsGapMove.
1037 chunk_->AddGapMove(cur_block->last_instruction_index() - 1, 1037 chunk_->AddGapMove(cur_block->last_instruction_index() - 1,
1038 operand, 1038 operand,
(...skipping 21 matching lines...) Expand all
1060 LiveRange* live_range = LiveRangeFor(phi->id()); 1060 LiveRange* live_range = LiveRangeFor(phi->id());
1061 LLabel* label = chunk_->GetLabel(phi->block()->block_id()); 1061 LLabel* label = chunk_->GetLabel(phi->block()->block_id());
1062 label->GetOrCreateParallelMove(LGap::START, chunk()->zone())-> 1062 label->GetOrCreateParallelMove(LGap::START, chunk()->zone())->
1063 AddMove(phi_operand, live_range->GetSpillOperand(), chunk()->zone()); 1063 AddMove(phi_operand, live_range->GetSpillOperand(), chunk()->zone());
1064 live_range->SetSpillStartIndex(phi->block()->first_instruction_index()); 1064 live_range->SetSpillStartIndex(phi->block()->first_instruction_index());
1065 } 1065 }
1066 } 1066 }
1067 1067
1068 1068
1069 bool LAllocator::Allocate(LChunk* chunk) { 1069 bool LAllocator::Allocate(LChunk* chunk) {
1070 ASSERT(chunk_ == NULL); 1070 DCHECK(chunk_ == NULL);
1071 chunk_ = static_cast<LPlatformChunk*>(chunk); 1071 chunk_ = static_cast<LPlatformChunk*>(chunk);
1072 assigned_registers_ = 1072 assigned_registers_ =
1073 new(chunk->zone()) BitVector(Register::NumAllocatableRegisters(), 1073 new(chunk->zone()) BitVector(Register::NumAllocatableRegisters(),
1074 chunk->zone()); 1074 chunk->zone());
1075 assigned_double_registers_ = 1075 assigned_double_registers_ =
1076 new(chunk->zone()) BitVector(DoubleRegister::NumAllocatableRegisters(), 1076 new(chunk->zone()) BitVector(DoubleRegister::NumAllocatableRegisters(),
1077 chunk->zone()); 1077 chunk->zone());
1078 MeetRegisterConstraints(); 1078 MeetRegisterConstraints();
1079 if (!AllocationOk()) return false; 1079 if (!AllocationOk()) return false;
1080 ResolvePhis(); 1080 ResolvePhis();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 HBasicBlock* pred) { 1118 HBasicBlock* pred) {
1119 LifetimePosition pred_end = 1119 LifetimePosition pred_end =
1120 LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); 1120 LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
1121 LifetimePosition cur_start = 1121 LifetimePosition cur_start =
1122 LifetimePosition::FromInstructionIndex(block->first_instruction_index()); 1122 LifetimePosition::FromInstructionIndex(block->first_instruction_index());
1123 LiveRange* pred_cover = NULL; 1123 LiveRange* pred_cover = NULL;
1124 LiveRange* cur_cover = NULL; 1124 LiveRange* cur_cover = NULL;
1125 LiveRange* cur_range = range; 1125 LiveRange* cur_range = range;
1126 while (cur_range != NULL && (cur_cover == NULL || pred_cover == NULL)) { 1126 while (cur_range != NULL && (cur_cover == NULL || pred_cover == NULL)) {
1127 if (cur_range->CanCover(cur_start)) { 1127 if (cur_range->CanCover(cur_start)) {
1128 ASSERT(cur_cover == NULL); 1128 DCHECK(cur_cover == NULL);
1129 cur_cover = cur_range; 1129 cur_cover = cur_range;
1130 } 1130 }
1131 if (cur_range->CanCover(pred_end)) { 1131 if (cur_range->CanCover(pred_end)) {
1132 ASSERT(pred_cover == NULL); 1132 DCHECK(pred_cover == NULL);
1133 pred_cover = cur_range; 1133 pred_cover = cur_range;
1134 } 1134 }
1135 cur_range = cur_range->next(); 1135 cur_range = cur_range->next();
1136 } 1136 }
1137 1137
1138 if (cur_cover->IsSpilled()) return; 1138 if (cur_cover->IsSpilled()) return;
1139 ASSERT(pred_cover != NULL && cur_cover != NULL); 1139 DCHECK(pred_cover != NULL && cur_cover != NULL);
1140 if (pred_cover != cur_cover) { 1140 if (pred_cover != cur_cover) {
1141 LOperand* pred_op = pred_cover->CreateAssignedOperand(chunk()->zone()); 1141 LOperand* pred_op = pred_cover->CreateAssignedOperand(chunk()->zone());
1142 LOperand* cur_op = cur_cover->CreateAssignedOperand(chunk()->zone()); 1142 LOperand* cur_op = cur_cover->CreateAssignedOperand(chunk()->zone());
1143 if (!pred_op->Equals(cur_op)) { 1143 if (!pred_op->Equals(cur_op)) {
1144 LGap* gap = NULL; 1144 LGap* gap = NULL;
1145 if (block->predecessors()->length() == 1) { 1145 if (block->predecessors()->length() == 1) {
1146 gap = GapAt(block->first_instruction_index()); 1146 gap = GapAt(block->first_instruction_index());
1147 } else { 1147 } else {
1148 ASSERT(pred->end()->SecondSuccessor() == NULL); 1148 DCHECK(pred->end()->SecondSuccessor() == NULL);
1149 gap = GetLastGap(pred); 1149 gap = GetLastGap(pred);
1150 1150
1151 // We are going to insert a move before the branch instruction. 1151 // We are going to insert a move before the branch instruction.
1152 // Some branch instructions (e.g. loops' back edges) 1152 // Some branch instructions (e.g. loops' back edges)
1153 // can potentially cause a GC so they have a pointer map. 1153 // can potentially cause a GC so they have a pointer map.
1154 // By inserting a move we essentially create a copy of a 1154 // By inserting a move we essentially create a copy of a
1155 // value which is invisible to PopulatePointerMaps(), because we store 1155 // value which is invisible to PopulatePointerMaps(), because we store
1156 // it into a location different from the operand of a live range 1156 // it into a location different from the operand of a live range
1157 // covering a branch instruction. 1157 // covering a branch instruction.
1158 // Thus we need to manually record a pointer. 1158 // Thus we need to manually record a pointer.
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 chunk()->zone()); 1287 chunk()->zone());
1288 for (int j = 0; j < move->move_operands()->length(); ++j) { 1288 for (int j = 0; j < move->move_operands()->length(); ++j) {
1289 LOperand* to = move->move_operands()->at(j).destination(); 1289 LOperand* to = move->move_operands()->at(j).destination();
1290 if (to->IsUnallocated() && 1290 if (to->IsUnallocated() &&
1291 LUnallocated::cast(to)->virtual_register() == phi->id()) { 1291 LUnallocated::cast(to)->virtual_register() == phi->id()) {
1292 hint = move->move_operands()->at(j).source(); 1292 hint = move->move_operands()->at(j).source();
1293 phi_operand = to; 1293 phi_operand = to;
1294 break; 1294 break;
1295 } 1295 }
1296 } 1296 }
1297 ASSERT(hint != NULL); 1297 DCHECK(hint != NULL);
1298 1298
1299 LifetimePosition block_start = LifetimePosition::FromInstructionIndex( 1299 LifetimePosition block_start = LifetimePosition::FromInstructionIndex(
1300 block->first_instruction_index()); 1300 block->first_instruction_index());
1301 Define(block_start, phi_operand, hint); 1301 Define(block_start, phi_operand, hint);
1302 } 1302 }
1303 1303
1304 // Now live is live_in for this block except not including values live 1304 // Now live is live_in for this block except not including values live
1305 // out on backward successor edges. 1305 // out on backward successor edges.
1306 live_in_sets_[block_id] = live; 1306 live_in_sets_[block_id] = live;
1307 1307
(...skipping 26 matching lines...) Expand all
1334 if (block_id == 0) { 1334 if (block_id == 0) {
1335 BitVector::Iterator iterator(live); 1335 BitVector::Iterator iterator(live);
1336 bool found = false; 1336 bool found = false;
1337 while (!iterator.Done()) { 1337 while (!iterator.Done()) {
1338 found = true; 1338 found = true;
1339 int operand_index = iterator.Current(); 1339 int operand_index = iterator.Current();
1340 if (chunk_->info()->IsStub()) { 1340 if (chunk_->info()->IsStub()) {
1341 CodeStub::Major major_key = chunk_->info()->code_stub()->MajorKey(); 1341 CodeStub::Major major_key = chunk_->info()->code_stub()->MajorKey();
1342 PrintF("Function: %s\n", CodeStub::MajorName(major_key, false)); 1342 PrintF("Function: %s\n", CodeStub::MajorName(major_key, false));
1343 } else { 1343 } else {
1344 ASSERT(chunk_->info()->IsOptimizing()); 1344 DCHECK(chunk_->info()->IsOptimizing());
1345 AllowHandleDereference allow_deref; 1345 AllowHandleDereference allow_deref;
1346 PrintF("Function: %s\n", 1346 PrintF("Function: %s\n",
1347 chunk_->info()->function()->debug_name()->ToCString().get()); 1347 chunk_->info()->function()->debug_name()->ToCString().get());
1348 } 1348 }
1349 PrintF("Value %d used before first definition!\n", operand_index); 1349 PrintF("Value %d used before first definition!\n", operand_index);
1350 LiveRange* range = LiveRangeFor(operand_index); 1350 LiveRange* range = LiveRangeFor(operand_index);
1351 PrintF("First use is at %d\n", range->first_pos()->pos().Value()); 1351 PrintF("First use is at %d\n", range->first_pos()->pos().Value());
1352 iterator.Advance(); 1352 iterator.Advance();
1353 } 1353 }
1354 ASSERT(!found); 1354 DCHECK(!found);
1355 } 1355 }
1356 #endif 1356 #endif
1357 } 1357 }
1358 1358
1359 for (int i = 0; i < live_ranges_.length(); ++i) { 1359 for (int i = 0; i < live_ranges_.length(); ++i) {
1360 if (live_ranges_[i] != NULL) { 1360 if (live_ranges_[i] != NULL) {
1361 live_ranges_[i]->kind_ = RequiredRegisterKind(live_ranges_[i]->id()); 1361 live_ranges_[i]->kind_ = RequiredRegisterKind(live_ranges_[i]->id());
1362 } 1362 }
1363 } 1363 }
1364 } 1364 }
1365 1365
1366 1366
1367 bool LAllocator::SafePointsAreInOrder() const { 1367 bool LAllocator::SafePointsAreInOrder() const {
1368 const ZoneList<LPointerMap*>* pointer_maps = chunk_->pointer_maps(); 1368 const ZoneList<LPointerMap*>* pointer_maps = chunk_->pointer_maps();
1369 int safe_point = 0; 1369 int safe_point = 0;
1370 for (int i = 0; i < pointer_maps->length(); ++i) { 1370 for (int i = 0; i < pointer_maps->length(); ++i) {
1371 LPointerMap* map = pointer_maps->at(i); 1371 LPointerMap* map = pointer_maps->at(i);
1372 if (safe_point > map->lithium_position()) return false; 1372 if (safe_point > map->lithium_position()) return false;
1373 safe_point = map->lithium_position(); 1373 safe_point = map->lithium_position();
1374 } 1374 }
1375 return true; 1375 return true;
1376 } 1376 }
1377 1377
1378 1378
1379 void LAllocator::PopulatePointerMaps() { 1379 void LAllocator::PopulatePointerMaps() {
1380 LAllocatorPhase phase("L_Populate pointer maps", this); 1380 LAllocatorPhase phase("L_Populate pointer maps", this);
1381 const ZoneList<LPointerMap*>* pointer_maps = chunk_->pointer_maps(); 1381 const ZoneList<LPointerMap*>* pointer_maps = chunk_->pointer_maps();
1382 1382
1383 ASSERT(SafePointsAreInOrder()); 1383 DCHECK(SafePointsAreInOrder());
1384 1384
1385 // Iterate over all safe point positions and record a pointer 1385 // Iterate over all safe point positions and record a pointer
1386 // for all spilled live ranges at this point. 1386 // for all spilled live ranges at this point.
1387 int first_safe_point_index = 0; 1387 int first_safe_point_index = 0;
1388 int last_range_start = 0; 1388 int last_range_start = 0;
1389 for (int range_idx = 0; range_idx < live_ranges()->length(); ++range_idx) { 1389 for (int range_idx = 0; range_idx < live_ranges()->length(); ++range_idx) {
1390 LiveRange* range = live_ranges()->at(range_idx); 1390 LiveRange* range = live_ranges()->at(range_idx);
1391 if (range == NULL) continue; 1391 if (range == NULL) continue;
1392 // Iterate over the first parts of multi-part live ranges. 1392 // Iterate over the first parts of multi-part live ranges.
1393 if (range->parent() != NULL) continue; 1393 if (range->parent() != NULL) continue;
1394 // Skip non-pointer values. 1394 // Skip non-pointer values.
1395 if (!HasTaggedValue(range->id())) continue; 1395 if (!HasTaggedValue(range->id())) continue;
1396 // Skip empty live ranges. 1396 // Skip empty live ranges.
1397 if (range->IsEmpty()) continue; 1397 if (range->IsEmpty()) continue;
1398 1398
1399 // Find the extent of the range and its children. 1399 // Find the extent of the range and its children.
1400 int start = range->Start().InstructionIndex(); 1400 int start = range->Start().InstructionIndex();
1401 int end = 0; 1401 int end = 0;
1402 for (LiveRange* cur = range; cur != NULL; cur = cur->next()) { 1402 for (LiveRange* cur = range; cur != NULL; cur = cur->next()) {
1403 LifetimePosition this_end = cur->End(); 1403 LifetimePosition this_end = cur->End();
1404 if (this_end.InstructionIndex() > end) end = this_end.InstructionIndex(); 1404 if (this_end.InstructionIndex() > end) end = this_end.InstructionIndex();
1405 ASSERT(cur->Start().InstructionIndex() >= start); 1405 DCHECK(cur->Start().InstructionIndex() >= start);
1406 } 1406 }
1407 1407
1408 // Most of the ranges are in order, but not all. Keep an eye on when 1408 // Most of the ranges are in order, but not all. Keep an eye on when
1409 // they step backwards and reset the first_safe_point_index so we don't 1409 // they step backwards and reset the first_safe_point_index so we don't
1410 // miss any safe points. 1410 // miss any safe points.
1411 if (start < last_range_start) { 1411 if (start < last_range_start) {
1412 first_safe_point_index = 0; 1412 first_safe_point_index = 0;
1413 } 1413 }
1414 last_range_start = start; 1414 last_range_start = start;
1415 1415
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n", 1449 TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n",
1450 range->id(), range->spill_start_index(), safe_point); 1450 range->id(), range->spill_start_index(), safe_point);
1451 map->RecordPointer(range->GetSpillOperand(), chunk()->zone()); 1451 map->RecordPointer(range->GetSpillOperand(), chunk()->zone());
1452 } 1452 }
1453 1453
1454 if (!cur->IsSpilled()) { 1454 if (!cur->IsSpilled()) {
1455 TraceAlloc("Pointer in register for range %d (start at %d) " 1455 TraceAlloc("Pointer in register for range %d (start at %d) "
1456 "at safe point %d\n", 1456 "at safe point %d\n",
1457 cur->id(), cur->Start().Value(), safe_point); 1457 cur->id(), cur->Start().Value(), safe_point);
1458 LOperand* operand = cur->CreateAssignedOperand(chunk()->zone()); 1458 LOperand* operand = cur->CreateAssignedOperand(chunk()->zone());
1459 ASSERT(!operand->IsStackSlot()); 1459 DCHECK(!operand->IsStackSlot());
1460 map->RecordPointer(operand, chunk()->zone()); 1460 map->RecordPointer(operand, chunk()->zone());
1461 } 1461 }
1462 } 1462 }
1463 } 1463 }
1464 } 1464 }
1465 1465
1466 1466
1467 void LAllocator::AllocateGeneralRegisters() { 1467 void LAllocator::AllocateGeneralRegisters() {
1468 LAllocatorPhase phase("L_Allocate general registers", this); 1468 LAllocatorPhase phase("L_Allocate general registers", this);
1469 num_registers_ = Register::NumAllocatableRegisters(); 1469 num_registers_ = Register::NumAllocatableRegisters();
1470 mode_ = GENERAL_REGISTERS; 1470 mode_ = GENERAL_REGISTERS;
1471 AllocateRegisters(); 1471 AllocateRegisters();
1472 } 1472 }
1473 1473
1474 1474
1475 void LAllocator::AllocateDoubleRegisters() { 1475 void LAllocator::AllocateDoubleRegisters() {
1476 LAllocatorPhase phase("L_Allocate double registers", this); 1476 LAllocatorPhase phase("L_Allocate double registers", this);
1477 num_registers_ = DoubleRegister::NumAllocatableRegisters(); 1477 num_registers_ = DoubleRegister::NumAllocatableRegisters();
1478 mode_ = DOUBLE_REGISTERS; 1478 mode_ = DOUBLE_REGISTERS;
1479 AllocateRegisters(); 1479 AllocateRegisters();
1480 } 1480 }
1481 1481
1482 1482
1483 void LAllocator::AllocateRegisters() { 1483 void LAllocator::AllocateRegisters() {
1484 ASSERT(unhandled_live_ranges_.is_empty()); 1484 DCHECK(unhandled_live_ranges_.is_empty());
1485 1485
1486 for (int i = 0; i < live_ranges_.length(); ++i) { 1486 for (int i = 0; i < live_ranges_.length(); ++i) {
1487 if (live_ranges_[i] != NULL) { 1487 if (live_ranges_[i] != NULL) {
1488 if (live_ranges_[i]->Kind() == mode_) { 1488 if (live_ranges_[i]->Kind() == mode_) {
1489 AddToUnhandledUnsorted(live_ranges_[i]); 1489 AddToUnhandledUnsorted(live_ranges_[i]);
1490 } 1490 }
1491 } 1491 }
1492 } 1492 }
1493 SortUnhandled(); 1493 SortUnhandled();
1494 ASSERT(UnhandledIsSorted()); 1494 DCHECK(UnhandledIsSorted());
1495 1495
1496 ASSERT(reusable_slots_.is_empty()); 1496 DCHECK(reusable_slots_.is_empty());
1497 ASSERT(active_live_ranges_.is_empty()); 1497 DCHECK(active_live_ranges_.is_empty());
1498 ASSERT(inactive_live_ranges_.is_empty()); 1498 DCHECK(inactive_live_ranges_.is_empty());
1499 1499
1500 if (mode_ == DOUBLE_REGISTERS) { 1500 if (mode_ == DOUBLE_REGISTERS) {
1501 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) { 1501 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) {
1502 LiveRange* current = fixed_double_live_ranges_.at(i); 1502 LiveRange* current = fixed_double_live_ranges_.at(i);
1503 if (current != NULL) { 1503 if (current != NULL) {
1504 AddToInactive(current); 1504 AddToInactive(current);
1505 } 1505 }
1506 } 1506 }
1507 } else { 1507 } else {
1508 ASSERT(mode_ == GENERAL_REGISTERS); 1508 DCHECK(mode_ == GENERAL_REGISTERS);
1509 for (int i = 0; i < fixed_live_ranges_.length(); ++i) { 1509 for (int i = 0; i < fixed_live_ranges_.length(); ++i) {
1510 LiveRange* current = fixed_live_ranges_.at(i); 1510 LiveRange* current = fixed_live_ranges_.at(i);
1511 if (current != NULL) { 1511 if (current != NULL) {
1512 AddToInactive(current); 1512 AddToInactive(current);
1513 } 1513 }
1514 } 1514 }
1515 } 1515 }
1516 1516
1517 while (!unhandled_live_ranges_.is_empty()) { 1517 while (!unhandled_live_ranges_.is_empty()) {
1518 ASSERT(UnhandledIsSorted()); 1518 DCHECK(UnhandledIsSorted());
1519 LiveRange* current = unhandled_live_ranges_.RemoveLast(); 1519 LiveRange* current = unhandled_live_ranges_.RemoveLast();
1520 ASSERT(UnhandledIsSorted()); 1520 DCHECK(UnhandledIsSorted());
1521 LifetimePosition position = current->Start(); 1521 LifetimePosition position = current->Start();
1522 #ifdef DEBUG 1522 #ifdef DEBUG
1523 allocation_finger_ = position; 1523 allocation_finger_ = position;
1524 #endif 1524 #endif
1525 TraceAlloc("Processing interval %d start=%d\n", 1525 TraceAlloc("Processing interval %d start=%d\n",
1526 current->id(), 1526 current->id(),
1527 position.Value()); 1527 position.Value());
1528 1528
1529 if (current->HasAllocatedSpillOperand()) { 1529 if (current->HasAllocatedSpillOperand()) {
1530 TraceAlloc("Live range %d already has a spill operand\n", current->id()); 1530 TraceAlloc("Live range %d already has a spill operand\n", current->id());
1531 LifetimePosition next_pos = position; 1531 LifetimePosition next_pos = position;
1532 if (IsGapAt(next_pos.InstructionIndex())) { 1532 if (IsGapAt(next_pos.InstructionIndex())) {
1533 next_pos = next_pos.NextInstruction(); 1533 next_pos = next_pos.NextInstruction();
1534 } 1534 }
1535 UsePosition* pos = current->NextUsePositionRegisterIsBeneficial(next_pos); 1535 UsePosition* pos = current->NextUsePositionRegisterIsBeneficial(next_pos);
1536 // If the range already has a spill operand and it doesn't need a 1536 // If the range already has a spill operand and it doesn't need a
1537 // register immediately, split it and spill the first part of the range. 1537 // register immediately, split it and spill the first part of the range.
1538 if (pos == NULL) { 1538 if (pos == NULL) {
1539 Spill(current); 1539 Spill(current);
1540 continue; 1540 continue;
1541 } else if (pos->pos().Value() > 1541 } else if (pos->pos().Value() >
1542 current->Start().NextInstruction().Value()) { 1542 current->Start().NextInstruction().Value()) {
1543 // Do not spill live range eagerly if use position that can benefit from 1543 // Do not spill live range eagerly if use position that can benefit from
1544 // the register is too close to the start of live range. 1544 // the register is too close to the start of live range.
1545 SpillBetween(current, current->Start(), pos->pos()); 1545 SpillBetween(current, current->Start(), pos->pos());
1546 if (!AllocationOk()) return; 1546 if (!AllocationOk()) return;
1547 ASSERT(UnhandledIsSorted()); 1547 DCHECK(UnhandledIsSorted());
1548 continue; 1548 continue;
1549 } 1549 }
1550 } 1550 }
1551 1551
1552 for (int i = 0; i < active_live_ranges_.length(); ++i) { 1552 for (int i = 0; i < active_live_ranges_.length(); ++i) {
1553 LiveRange* cur_active = active_live_ranges_.at(i); 1553 LiveRange* cur_active = active_live_ranges_.at(i);
1554 if (cur_active->End().Value() <= position.Value()) { 1554 if (cur_active->End().Value() <= position.Value()) {
1555 ActiveToHandled(cur_active); 1555 ActiveToHandled(cur_active);
1556 --i; // The live range was removed from the list of active live ranges. 1556 --i; // The live range was removed from the list of active live ranges.
1557 } else if (!cur_active->Covers(position)) { 1557 } else if (!cur_active->Covers(position)) {
1558 ActiveToInactive(cur_active); 1558 ActiveToInactive(cur_active);
1559 --i; // The live range was removed from the list of active live ranges. 1559 --i; // The live range was removed from the list of active live ranges.
1560 } 1560 }
1561 } 1561 }
1562 1562
1563 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { 1563 for (int i = 0; i < inactive_live_ranges_.length(); ++i) {
1564 LiveRange* cur_inactive = inactive_live_ranges_.at(i); 1564 LiveRange* cur_inactive = inactive_live_ranges_.at(i);
1565 if (cur_inactive->End().Value() <= position.Value()) { 1565 if (cur_inactive->End().Value() <= position.Value()) {
1566 InactiveToHandled(cur_inactive); 1566 InactiveToHandled(cur_inactive);
1567 --i; // Live range was removed from the list of inactive live ranges. 1567 --i; // Live range was removed from the list of inactive live ranges.
1568 } else if (cur_inactive->Covers(position)) { 1568 } else if (cur_inactive->Covers(position)) {
1569 InactiveToActive(cur_inactive); 1569 InactiveToActive(cur_inactive);
1570 --i; // Live range was removed from the list of inactive live ranges. 1570 --i; // Live range was removed from the list of inactive live ranges.
1571 } 1571 }
1572 } 1572 }
1573 1573
1574 ASSERT(!current->HasRegisterAssigned() && !current->IsSpilled()); 1574 DCHECK(!current->HasRegisterAssigned() && !current->IsSpilled());
1575 1575
1576 bool result = TryAllocateFreeReg(current); 1576 bool result = TryAllocateFreeReg(current);
1577 if (!AllocationOk()) return; 1577 if (!AllocationOk()) return;
1578 1578
1579 if (!result) AllocateBlockedReg(current); 1579 if (!result) AllocateBlockedReg(current);
1580 if (!AllocationOk()) return; 1580 if (!AllocationOk()) return;
1581 1581
1582 if (current->HasRegisterAssigned()) { 1582 if (current->HasRegisterAssigned()) {
1583 AddToActive(current); 1583 AddToActive(current);
1584 } 1584 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1638 1638
1639 1639
1640 void LAllocator::AddToInactive(LiveRange* range) { 1640 void LAllocator::AddToInactive(LiveRange* range) {
1641 TraceAlloc("Add live range %d to inactive\n", range->id()); 1641 TraceAlloc("Add live range %d to inactive\n", range->id());
1642 inactive_live_ranges_.Add(range, zone()); 1642 inactive_live_ranges_.Add(range, zone());
1643 } 1643 }
1644 1644
1645 1645
1646 void LAllocator::AddToUnhandledSorted(LiveRange* range) { 1646 void LAllocator::AddToUnhandledSorted(LiveRange* range) {
1647 if (range == NULL || range->IsEmpty()) return; 1647 if (range == NULL || range->IsEmpty()) return;
1648 ASSERT(!range->HasRegisterAssigned() && !range->IsSpilled()); 1648 DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
1649 ASSERT(allocation_finger_.Value() <= range->Start().Value()); 1649 DCHECK(allocation_finger_.Value() <= range->Start().Value());
1650 for (int i = unhandled_live_ranges_.length() - 1; i >= 0; --i) { 1650 for (int i = unhandled_live_ranges_.length() - 1; i >= 0; --i) {
1651 LiveRange* cur_range = unhandled_live_ranges_.at(i); 1651 LiveRange* cur_range = unhandled_live_ranges_.at(i);
1652 if (range->ShouldBeAllocatedBefore(cur_range)) { 1652 if (range->ShouldBeAllocatedBefore(cur_range)) {
1653 TraceAlloc("Add live range %d to unhandled at %d\n", range->id(), i + 1); 1653 TraceAlloc("Add live range %d to unhandled at %d\n", range->id(), i + 1);
1654 unhandled_live_ranges_.InsertAt(i + 1, range, zone()); 1654 unhandled_live_ranges_.InsertAt(i + 1, range, zone());
1655 ASSERT(UnhandledIsSorted()); 1655 DCHECK(UnhandledIsSorted());
1656 return; 1656 return;
1657 } 1657 }
1658 } 1658 }
1659 TraceAlloc("Add live range %d to unhandled at start\n", range->id()); 1659 TraceAlloc("Add live range %d to unhandled at start\n", range->id());
1660 unhandled_live_ranges_.InsertAt(0, range, zone()); 1660 unhandled_live_ranges_.InsertAt(0, range, zone());
1661 ASSERT(UnhandledIsSorted()); 1661 DCHECK(UnhandledIsSorted());
1662 } 1662 }
1663 1663
1664 1664
1665 void LAllocator::AddToUnhandledUnsorted(LiveRange* range) { 1665 void LAllocator::AddToUnhandledUnsorted(LiveRange* range) {
1666 if (range == NULL || range->IsEmpty()) return; 1666 if (range == NULL || range->IsEmpty()) return;
1667 ASSERT(!range->HasRegisterAssigned() && !range->IsSpilled()); 1667 DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
1668 TraceAlloc("Add live range %d to unhandled unsorted at end\n", range->id()); 1668 TraceAlloc("Add live range %d to unhandled unsorted at end\n", range->id());
1669 unhandled_live_ranges_.Add(range, zone()); 1669 unhandled_live_ranges_.Add(range, zone());
1670 } 1670 }
1671 1671
1672 1672
1673 static int UnhandledSortHelper(LiveRange* const* a, LiveRange* const* b) { 1673 static int UnhandledSortHelper(LiveRange* const* a, LiveRange* const* b) {
1674 ASSERT(!(*a)->ShouldBeAllocatedBefore(*b) || 1674 DCHECK(!(*a)->ShouldBeAllocatedBefore(*b) ||
1675 !(*b)->ShouldBeAllocatedBefore(*a)); 1675 !(*b)->ShouldBeAllocatedBefore(*a));
1676 if ((*a)->ShouldBeAllocatedBefore(*b)) return 1; 1676 if ((*a)->ShouldBeAllocatedBefore(*b)) return 1;
1677 if ((*b)->ShouldBeAllocatedBefore(*a)) return -1; 1677 if ((*b)->ShouldBeAllocatedBefore(*a)) return -1;
1678 return (*a)->id() - (*b)->id(); 1678 return (*a)->id() - (*b)->id();
1679 } 1679 }
1680 1680
1681 1681
1682 // Sort the unhandled live ranges so that the ranges to be processed first are 1682 // Sort the unhandled live ranges so that the ranges to be processed first are
1683 // at the end of the array list. This is convenient for the register allocation 1683 // at the end of the array list. This is convenient for the register allocation
1684 // algorithm because it is efficient to remove elements from the end. 1684 // algorithm because it is efficient to remove elements from the end.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1718 range->TopLevel()->Start().Value()) { 1718 range->TopLevel()->Start().Value()) {
1719 return NULL; 1719 return NULL;
1720 } 1720 }
1721 LOperand* result = reusable_slots_.first()->TopLevel()->GetSpillOperand(); 1721 LOperand* result = reusable_slots_.first()->TopLevel()->GetSpillOperand();
1722 reusable_slots_.Remove(0); 1722 reusable_slots_.Remove(0);
1723 return result; 1723 return result;
1724 } 1724 }
1725 1725
1726 1726
1727 void LAllocator::ActiveToHandled(LiveRange* range) { 1727 void LAllocator::ActiveToHandled(LiveRange* range) {
1728 ASSERT(active_live_ranges_.Contains(range)); 1728 DCHECK(active_live_ranges_.Contains(range));
1729 active_live_ranges_.RemoveElement(range); 1729 active_live_ranges_.RemoveElement(range);
1730 TraceAlloc("Moving live range %d from active to handled\n", range->id()); 1730 TraceAlloc("Moving live range %d from active to handled\n", range->id());
1731 FreeSpillSlot(range); 1731 FreeSpillSlot(range);
1732 } 1732 }
1733 1733
1734 1734
1735 void LAllocator::ActiveToInactive(LiveRange* range) { 1735 void LAllocator::ActiveToInactive(LiveRange* range) {
1736 ASSERT(active_live_ranges_.Contains(range)); 1736 DCHECK(active_live_ranges_.Contains(range));
1737 active_live_ranges_.RemoveElement(range); 1737 active_live_ranges_.RemoveElement(range);
1738 inactive_live_ranges_.Add(range, zone()); 1738 inactive_live_ranges_.Add(range, zone());
1739 TraceAlloc("Moving live range %d from active to inactive\n", range->id()); 1739 TraceAlloc("Moving live range %d from active to inactive\n", range->id());
1740 } 1740 }
1741 1741
1742 1742
1743 void LAllocator::InactiveToHandled(LiveRange* range) { 1743 void LAllocator::InactiveToHandled(LiveRange* range) {
1744 ASSERT(inactive_live_ranges_.Contains(range)); 1744 DCHECK(inactive_live_ranges_.Contains(range));
1745 inactive_live_ranges_.RemoveElement(range); 1745 inactive_live_ranges_.RemoveElement(range);
1746 TraceAlloc("Moving live range %d from inactive to handled\n", range->id()); 1746 TraceAlloc("Moving live range %d from inactive to handled\n", range->id());
1747 FreeSpillSlot(range); 1747 FreeSpillSlot(range);
1748 } 1748 }
1749 1749
1750 1750
1751 void LAllocator::InactiveToActive(LiveRange* range) { 1751 void LAllocator::InactiveToActive(LiveRange* range) {
1752 ASSERT(inactive_live_ranges_.Contains(range)); 1752 DCHECK(inactive_live_ranges_.Contains(range));
1753 inactive_live_ranges_.RemoveElement(range); 1753 inactive_live_ranges_.RemoveElement(range);
1754 active_live_ranges_.Add(range, zone()); 1754 active_live_ranges_.Add(range, zone());
1755 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); 1755 TraceAlloc("Moving live range %d from inactive to active\n", range->id());
1756 } 1756 }
1757 1757
1758 1758
1759 // TryAllocateFreeReg and AllocateBlockedReg assume this 1759 // TryAllocateFreeReg and AllocateBlockedReg assume this
1760 // when allocating local arrays. 1760 // when allocating local arrays.
1761 STATIC_ASSERT(DoubleRegister::kMaxNumAllocatableRegisters >= 1761 STATIC_ASSERT(DoubleRegister::kMaxNumAllocatableRegisters >=
1762 Register::kMaxNumAllocatableRegisters); 1762 Register::kMaxNumAllocatableRegisters);
1763 1763
1764 1764
1765 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { 1765 bool LAllocator::TryAllocateFreeReg(LiveRange* current) {
1766 LifetimePosition free_until_pos[DoubleRegister::kMaxNumAllocatableRegisters]; 1766 LifetimePosition free_until_pos[DoubleRegister::kMaxNumAllocatableRegisters];
1767 1767
1768 for (int i = 0; i < num_registers_; i++) { 1768 for (int i = 0; i < num_registers_; i++) {
1769 free_until_pos[i] = LifetimePosition::MaxPosition(); 1769 free_until_pos[i] = LifetimePosition::MaxPosition();
1770 } 1770 }
1771 1771
1772 for (int i = 0; i < active_live_ranges_.length(); ++i) { 1772 for (int i = 0; i < active_live_ranges_.length(); ++i) {
1773 LiveRange* cur_active = active_live_ranges_.at(i); 1773 LiveRange* cur_active = active_live_ranges_.at(i);
1774 free_until_pos[cur_active->assigned_register()] = 1774 free_until_pos[cur_active->assigned_register()] =
1775 LifetimePosition::FromInstructionIndex(0); 1775 LifetimePosition::FromInstructionIndex(0);
1776 } 1776 }
1777 1777
1778 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { 1778 for (int i = 0; i < inactive_live_ranges_.length(); ++i) {
1779 LiveRange* cur_inactive = inactive_live_ranges_.at(i); 1779 LiveRange* cur_inactive = inactive_live_ranges_.at(i);
1780 ASSERT(cur_inactive->End().Value() > current->Start().Value()); 1780 DCHECK(cur_inactive->End().Value() > current->Start().Value());
1781 LifetimePosition next_intersection = 1781 LifetimePosition next_intersection =
1782 cur_inactive->FirstIntersection(current); 1782 cur_inactive->FirstIntersection(current);
1783 if (!next_intersection.IsValid()) continue; 1783 if (!next_intersection.IsValid()) continue;
1784 int cur_reg = cur_inactive->assigned_register(); 1784 int cur_reg = cur_inactive->assigned_register();
1785 free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection); 1785 free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
1786 } 1786 }
1787 1787
1788 LOperand* hint = current->FirstHint(); 1788 LOperand* hint = current->FirstHint();
1789 if (hint != NULL && (hint->IsRegister() || hint->IsDoubleRegister())) { 1789 if (hint != NULL && (hint->IsRegister() || hint->IsDoubleRegister())) {
1790 int register_index = hint->index(); 1790 int register_index = hint->index();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1824 // Register reg is available at the range start but becomes blocked before 1824 // Register reg is available at the range start but becomes blocked before
1825 // the range end. Split current at position where it becomes blocked. 1825 // the range end. Split current at position where it becomes blocked.
1826 LiveRange* tail = SplitRangeAt(current, pos); 1826 LiveRange* tail = SplitRangeAt(current, pos);
1827 if (!AllocationOk()) return false; 1827 if (!AllocationOk()) return false;
1828 AddToUnhandledSorted(tail); 1828 AddToUnhandledSorted(tail);
1829 } 1829 }
1830 1830
1831 1831
1832 // Register reg is available at the range start and is free until 1832 // Register reg is available at the range start and is free until
1833 // the range end. 1833 // the range end.
1834 ASSERT(pos.Value() >= current->End().Value()); 1834 DCHECK(pos.Value() >= current->End().Value());
1835 TraceAlloc("Assigning free reg %s to live range %d\n", 1835 TraceAlloc("Assigning free reg %s to live range %d\n",
1836 RegisterName(reg), 1836 RegisterName(reg),
1837 current->id()); 1837 current->id());
1838 SetLiveRangeAssignedRegister(current, reg); 1838 SetLiveRangeAssignedRegister(current, reg);
1839 1839
1840 return true; 1840 return true;
1841 } 1841 }
1842 1842
1843 1843
1844 void LAllocator::AllocateBlockedReg(LiveRange* current) { 1844 void LAllocator::AllocateBlockedReg(LiveRange* current) {
(...skipping 25 matching lines...) Expand all
1870 if (next_use == NULL) { 1870 if (next_use == NULL) {
1871 use_pos[cur_reg] = range->End(); 1871 use_pos[cur_reg] = range->End();
1872 } else { 1872 } else {
1873 use_pos[cur_reg] = next_use->pos(); 1873 use_pos[cur_reg] = next_use->pos();
1874 } 1874 }
1875 } 1875 }
1876 } 1876 }
1877 1877
1878 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { 1878 for (int i = 0; i < inactive_live_ranges_.length(); ++i) {
1879 LiveRange* range = inactive_live_ranges_.at(i); 1879 LiveRange* range = inactive_live_ranges_.at(i);
1880 ASSERT(range->End().Value() > current->Start().Value()); 1880 DCHECK(range->End().Value() > current->Start().Value());
1881 LifetimePosition next_intersection = range->FirstIntersection(current); 1881 LifetimePosition next_intersection = range->FirstIntersection(current);
1882 if (!next_intersection.IsValid()) continue; 1882 if (!next_intersection.IsValid()) continue;
1883 int cur_reg = range->assigned_register(); 1883 int cur_reg = range->assigned_register();
1884 if (range->IsFixed()) { 1884 if (range->IsFixed()) {
1885 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); 1885 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
1886 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); 1886 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
1887 } else { 1887 } else {
1888 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); 1888 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
1889 } 1889 }
1890 } 1890 }
(...skipping 18 matching lines...) Expand all
1909 // Register becomes blocked before the current range end. Split before that 1909 // Register becomes blocked before the current range end. Split before that
1910 // position. 1910 // position.
1911 LiveRange* tail = SplitBetween(current, 1911 LiveRange* tail = SplitBetween(current,
1912 current->Start(), 1912 current->Start(),
1913 block_pos[reg].InstructionStart()); 1913 block_pos[reg].InstructionStart());
1914 if (!AllocationOk()) return; 1914 if (!AllocationOk()) return;
1915 AddToUnhandledSorted(tail); 1915 AddToUnhandledSorted(tail);
1916 } 1916 }
1917 1917
1918 // Register reg is not blocked for the whole range. 1918 // Register reg is not blocked for the whole range.
1919 ASSERT(block_pos[reg].Value() >= current->End().Value()); 1919 DCHECK(block_pos[reg].Value() >= current->End().Value());
1920 TraceAlloc("Assigning blocked reg %s to live range %d\n", 1920 TraceAlloc("Assigning blocked reg %s to live range %d\n",
1921 RegisterName(reg), 1921 RegisterName(reg),
1922 current->id()); 1922 current->id());
1923 SetLiveRangeAssignedRegister(current, reg); 1923 SetLiveRangeAssignedRegister(current, reg);
1924 1924
1925 // This register was not free. Thus we need to find and spill 1925 // This register was not free. Thus we need to find and spill
1926 // parts of active and inactive live regions that use the same register 1926 // parts of active and inactive live regions that use the same register
1927 // at the same lifetime positions as current. 1927 // at the same lifetime positions as current.
1928 SplitAndSpillIntersecting(current); 1928 SplitAndSpillIntersecting(current);
1929 } 1929 }
(...skipping 26 matching lines...) Expand all
1956 1956
1957 // Try hoisting out to an outer loop. 1957 // Try hoisting out to an outer loop.
1958 loop_header = loop_header->parent_loop_header(); 1958 loop_header = loop_header->parent_loop_header();
1959 } 1959 }
1960 1960
1961 return pos; 1961 return pos;
1962 } 1962 }
1963 1963
1964 1964
1965 void LAllocator::SplitAndSpillIntersecting(LiveRange* current) { 1965 void LAllocator::SplitAndSpillIntersecting(LiveRange* current) {
1966 ASSERT(current->HasRegisterAssigned()); 1966 DCHECK(current->HasRegisterAssigned());
1967 int reg = current->assigned_register(); 1967 int reg = current->assigned_register();
1968 LifetimePosition split_pos = current->Start(); 1968 LifetimePosition split_pos = current->Start();
1969 for (int i = 0; i < active_live_ranges_.length(); ++i) { 1969 for (int i = 0; i < active_live_ranges_.length(); ++i) {
1970 LiveRange* range = active_live_ranges_[i]; 1970 LiveRange* range = active_live_ranges_[i];
1971 if (range->assigned_register() == reg) { 1971 if (range->assigned_register() == reg) {
1972 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); 1972 UsePosition* next_pos = range->NextRegisterPosition(current->Start());
1973 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos); 1973 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
1974 if (next_pos == NULL) { 1974 if (next_pos == NULL) {
1975 SpillAfter(range, spill_pos); 1975 SpillAfter(range, spill_pos);
1976 } else { 1976 } else {
1977 // When spilling between spill_pos and next_pos ensure that the range 1977 // When spilling between spill_pos and next_pos ensure that the range
1978 // remains spilled at least until the start of the current live range. 1978 // remains spilled at least until the start of the current live range.
1979 // This guarantees that we will not introduce new unhandled ranges that 1979 // This guarantees that we will not introduce new unhandled ranges that
1980 // start before the current range as this violates allocation invariant 1980 // start before the current range as this violates allocation invariant
1981 // and will lead to an inconsistent state of active and inactive 1981 // and will lead to an inconsistent state of active and inactive
1982 // live-ranges: ranges are allocated in order of their start positions, 1982 // live-ranges: ranges are allocated in order of their start positions,
1983 // ranges are retired from active/inactive when the start of the 1983 // ranges are retired from active/inactive when the start of the
1984 // current live-range is larger than their end. 1984 // current live-range is larger than their end.
1985 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos()); 1985 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
1986 } 1986 }
1987 if (!AllocationOk()) return; 1987 if (!AllocationOk()) return;
1988 ActiveToHandled(range); 1988 ActiveToHandled(range);
1989 --i; 1989 --i;
1990 } 1990 }
1991 } 1991 }
1992 1992
1993 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { 1993 for (int i = 0; i < inactive_live_ranges_.length(); ++i) {
1994 LiveRange* range = inactive_live_ranges_[i]; 1994 LiveRange* range = inactive_live_ranges_[i];
1995 ASSERT(range->End().Value() > current->Start().Value()); 1995 DCHECK(range->End().Value() > current->Start().Value());
1996 if (range->assigned_register() == reg && !range->IsFixed()) { 1996 if (range->assigned_register() == reg && !range->IsFixed()) {
1997 LifetimePosition next_intersection = range->FirstIntersection(current); 1997 LifetimePosition next_intersection = range->FirstIntersection(current);
1998 if (next_intersection.IsValid()) { 1998 if (next_intersection.IsValid()) {
1999 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); 1999 UsePosition* next_pos = range->NextRegisterPosition(current->Start());
2000 if (next_pos == NULL) { 2000 if (next_pos == NULL) {
2001 SpillAfter(range, split_pos); 2001 SpillAfter(range, split_pos);
2002 } else { 2002 } else {
2003 next_intersection = Min(next_intersection, next_pos->pos()); 2003 next_intersection = Min(next_intersection, next_pos->pos());
2004 SpillBetween(range, split_pos, next_intersection); 2004 SpillBetween(range, split_pos, next_intersection);
2005 } 2005 }
2006 if (!AllocationOk()) return; 2006 if (!AllocationOk()) return;
2007 InactiveToHandled(range); 2007 InactiveToHandled(range);
2008 --i; 2008 --i;
2009 } 2009 }
2010 } 2010 }
2011 } 2011 }
2012 } 2012 }
2013 2013
2014 2014
2015 bool LAllocator::IsBlockBoundary(LifetimePosition pos) { 2015 bool LAllocator::IsBlockBoundary(LifetimePosition pos) {
2016 return pos.IsInstructionStart() && 2016 return pos.IsInstructionStart() &&
2017 InstructionAt(pos.InstructionIndex())->IsLabel(); 2017 InstructionAt(pos.InstructionIndex())->IsLabel();
2018 } 2018 }
2019 2019
2020 2020
2021 LiveRange* LAllocator::SplitRangeAt(LiveRange* range, LifetimePosition pos) { 2021 LiveRange* LAllocator::SplitRangeAt(LiveRange* range, LifetimePosition pos) {
2022 ASSERT(!range->IsFixed()); 2022 DCHECK(!range->IsFixed());
2023 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value()); 2023 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value());
2024 2024
2025 if (pos.Value() <= range->Start().Value()) return range; 2025 if (pos.Value() <= range->Start().Value()) return range;
2026 2026
2027 // We can't properly connect liveranges if split occured at the end 2027 // We can't properly connect liveranges if split occured at the end
2028 // of control instruction. 2028 // of control instruction.
2029 ASSERT(pos.IsInstructionStart() || 2029 DCHECK(pos.IsInstructionStart() ||
2030 !chunk_->instructions()->at(pos.InstructionIndex())->IsControl()); 2030 !chunk_->instructions()->at(pos.InstructionIndex())->IsControl());
2031 2031
2032 int vreg = GetVirtualRegister(); 2032 int vreg = GetVirtualRegister();
2033 if (!AllocationOk()) return NULL; 2033 if (!AllocationOk()) return NULL;
2034 LiveRange* result = LiveRangeFor(vreg); 2034 LiveRange* result = LiveRangeFor(vreg);
2035 range->SplitAt(pos, result, zone()); 2035 range->SplitAt(pos, result, zone());
2036 return result; 2036 return result;
2037 } 2037 }
2038 2038
2039 2039
2040 LiveRange* LAllocator::SplitBetween(LiveRange* range, 2040 LiveRange* LAllocator::SplitBetween(LiveRange* range,
2041 LifetimePosition start, 2041 LifetimePosition start,
2042 LifetimePosition end) { 2042 LifetimePosition end) {
2043 ASSERT(!range->IsFixed()); 2043 DCHECK(!range->IsFixed());
2044 TraceAlloc("Splitting live range %d in position between [%d, %d]\n", 2044 TraceAlloc("Splitting live range %d in position between [%d, %d]\n",
2045 range->id(), 2045 range->id(),
2046 start.Value(), 2046 start.Value(),
2047 end.Value()); 2047 end.Value());
2048 2048
2049 LifetimePosition split_pos = FindOptimalSplitPos(start, end); 2049 LifetimePosition split_pos = FindOptimalSplitPos(start, end);
2050 ASSERT(split_pos.Value() >= start.Value()); 2050 DCHECK(split_pos.Value() >= start.Value());
2051 return SplitRangeAt(range, split_pos); 2051 return SplitRangeAt(range, split_pos);
2052 } 2052 }
2053 2053
2054 2054
2055 LifetimePosition LAllocator::FindOptimalSplitPos(LifetimePosition start, 2055 LifetimePosition LAllocator::FindOptimalSplitPos(LifetimePosition start,
2056 LifetimePosition end) { 2056 LifetimePosition end) {
2057 int start_instr = start.InstructionIndex(); 2057 int start_instr = start.InstructionIndex();
2058 int end_instr = end.InstructionIndex(); 2058 int end_instr = end.InstructionIndex();
2059 ASSERT(start_instr <= end_instr); 2059 DCHECK(start_instr <= end_instr);
2060 2060
2061 // We have no choice 2061 // We have no choice
2062 if (start_instr == end_instr) return end; 2062 if (start_instr == end_instr) return end;
2063 2063
2064 HBasicBlock* start_block = GetBlock(start); 2064 HBasicBlock* start_block = GetBlock(start);
2065 HBasicBlock* end_block = GetBlock(end); 2065 HBasicBlock* end_block = GetBlock(end);
2066 2066
2067 if (end_block == start_block) { 2067 if (end_block == start_block) {
2068 // The interval is split in the same basic block. Split at the latest 2068 // The interval is split in the same basic block. Split at the latest
2069 // possible position. 2069 // possible position.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2111 if (second_part->Start().Value() < end.Value()) { 2111 if (second_part->Start().Value() < end.Value()) {
2112 // The split result intersects with [start, end[. 2112 // The split result intersects with [start, end[.
2113 // Split it at position between ]start+1, end[, spill the middle part 2113 // Split it at position between ]start+1, end[, spill the middle part
2114 // and put the rest to unhandled. 2114 // and put the rest to unhandled.
2115 LiveRange* third_part = SplitBetween( 2115 LiveRange* third_part = SplitBetween(
2116 second_part, 2116 second_part,
2117 Max(second_part->Start().InstructionEnd(), until), 2117 Max(second_part->Start().InstructionEnd(), until),
2118 end.PrevInstruction().InstructionEnd()); 2118 end.PrevInstruction().InstructionEnd());
2119 if (!AllocationOk()) return; 2119 if (!AllocationOk()) return;
2120 2120
2121 ASSERT(third_part != second_part); 2121 DCHECK(third_part != second_part);
2122 2122
2123 Spill(second_part); 2123 Spill(second_part);
2124 AddToUnhandledSorted(third_part); 2124 AddToUnhandledSorted(third_part);
2125 } else { 2125 } else {
2126 // The split result does not intersect with [start, end[. 2126 // The split result does not intersect with [start, end[.
2127 // Nothing to spill. Just put it to unhandled as whole. 2127 // Nothing to spill. Just put it to unhandled as whole.
2128 AddToUnhandledSorted(second_part); 2128 AddToUnhandledSorted(second_part);
2129 } 2129 }
2130 } 2130 }
2131 2131
2132 2132
2133 void LAllocator::Spill(LiveRange* range) { 2133 void LAllocator::Spill(LiveRange* range) {
2134 ASSERT(!range->IsSpilled()); 2134 DCHECK(!range->IsSpilled());
2135 TraceAlloc("Spilling live range %d\n", range->id()); 2135 TraceAlloc("Spilling live range %d\n", range->id());
2136 LiveRange* first = range->TopLevel(); 2136 LiveRange* first = range->TopLevel();
2137 2137
2138 if (!first->HasAllocatedSpillOperand()) { 2138 if (!first->HasAllocatedSpillOperand()) {
2139 LOperand* op = TryReuseSpillSlot(range); 2139 LOperand* op = TryReuseSpillSlot(range);
2140 if (op == NULL) op = chunk_->GetNextSpillSlot(range->Kind()); 2140 if (op == NULL) op = chunk_->GetNextSpillSlot(range->Kind());
2141 first->SetSpillOperand(op); 2141 first->SetSpillOperand(op);
2142 } 2142 }
2143 range->MakeSpilled(chunk()->zone()); 2143 range->MakeSpilled(chunk()->zone());
2144 } 2144 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2185 isolate()->GetHTracer()->TraceLiveRanges(name(), allocator_); 2185 isolate()->GetHTracer()->TraceLiveRanges(name(), allocator_);
2186 } 2186 }
2187 2187
2188 #ifdef DEBUG 2188 #ifdef DEBUG
2189 if (allocator_ != NULL) allocator_->Verify(); 2189 if (allocator_ != NULL) allocator_->Verify();
2190 #endif 2190 #endif
2191 } 2191 }
2192 2192
2193 2193
2194 } } // namespace v8::internal 2194 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/lithium-allocator.h ('k') | src/lithium-allocator-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698