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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 bool UsePosition::RequiresRegister() const { | 103 bool UsePosition::RequiresRegister() const { |
104 return requires_reg_; | 104 return requires_reg_; |
105 } | 105 } |
106 | 106 |
107 | 107 |
108 bool UsePosition::RegisterIsBeneficial() const { | 108 bool UsePosition::RegisterIsBeneficial() const { |
109 return register_beneficial_; | 109 return register_beneficial_; |
110 } | 110 } |
111 | 111 |
112 | 112 |
113 void UseInterval::SplitAt(LifetimePosition pos) { | 113 void UseInterval::SplitAt(LifetimePosition pos, Zone* zone) { |
114 ASSERT(Contains(pos) && pos.Value() != start().Value()); | 114 ASSERT(Contains(pos) && pos.Value() != start().Value()); |
115 UseInterval* after = new UseInterval(pos, end_); | 115 UseInterval* after = new(zone) UseInterval(pos, end_); |
116 after->next_ = next_; | 116 after->next_ = next_; |
117 next_ = after; | 117 next_ = after; |
118 end_ = pos; | 118 end_ = pos; |
119 } | 119 } |
120 | 120 |
121 | 121 |
122 #ifdef DEBUG | 122 #ifdef DEBUG |
123 | 123 |
124 | 124 |
125 void LiveRange::Verify() const { | 125 void LiveRange::Verify() const { |
(...skipping 16 matching lines...) Expand all Loading... |
142 } | 142 } |
143 current_interval = current_interval->next(); | 143 current_interval = current_interval->next(); |
144 } | 144 } |
145 return false; | 145 return false; |
146 } | 146 } |
147 | 147 |
148 | 148 |
149 #endif | 149 #endif |
150 | 150 |
151 | 151 |
152 LiveRange::LiveRange(int id) | 152 LiveRange::LiveRange(int id, Zone* zone) |
153 : id_(id), | 153 : id_(id), |
154 spilled_(false), | 154 spilled_(false), |
155 is_double_(false), | 155 is_double_(false), |
156 assigned_register_(kInvalidAssignment), | 156 assigned_register_(kInvalidAssignment), |
157 last_interval_(NULL), | 157 last_interval_(NULL), |
158 first_interval_(NULL), | 158 first_interval_(NULL), |
159 first_pos_(NULL), | 159 first_pos_(NULL), |
160 parent_(NULL), | 160 parent_(NULL), |
161 next_(NULL), | 161 next_(NULL), |
162 current_interval_(NULL), | 162 current_interval_(NULL), |
163 last_processed_use_(NULL), | 163 last_processed_use_(NULL), |
164 spill_operand_(new LOperand()), | 164 spill_operand_(new(zone) LOperand()), |
165 spill_start_index_(kMaxInt) { } | 165 spill_start_index_(kMaxInt) { } |
166 | 166 |
167 | 167 |
168 void LiveRange::set_assigned_register(int reg, RegisterKind register_kind) { | 168 void LiveRange::set_assigned_register(int reg, |
| 169 RegisterKind register_kind, |
| 170 Zone* zone) { |
169 ASSERT(!HasRegisterAssigned() && !IsSpilled()); | 171 ASSERT(!HasRegisterAssigned() && !IsSpilled()); |
170 assigned_register_ = reg; | 172 assigned_register_ = reg; |
171 is_double_ = (register_kind == DOUBLE_REGISTERS); | 173 is_double_ = (register_kind == DOUBLE_REGISTERS); |
172 ConvertOperands(); | 174 ConvertOperands(zone); |
173 } | 175 } |
174 | 176 |
175 | 177 |
176 void LiveRange::MakeSpilled() { | 178 void LiveRange::MakeSpilled(Zone* zone) { |
177 ASSERT(!IsSpilled()); | 179 ASSERT(!IsSpilled()); |
178 ASSERT(TopLevel()->HasAllocatedSpillOperand()); | 180 ASSERT(TopLevel()->HasAllocatedSpillOperand()); |
179 spilled_ = true; | 181 spilled_ = true; |
180 assigned_register_ = kInvalidAssignment; | 182 assigned_register_ = kInvalidAssignment; |
181 ConvertOperands(); | 183 ConvertOperands(zone); |
182 } | 184 } |
183 | 185 |
184 | 186 |
185 bool LiveRange::HasAllocatedSpillOperand() const { | 187 bool LiveRange::HasAllocatedSpillOperand() const { |
186 ASSERT(spill_operand_ != NULL); | 188 ASSERT(spill_operand_ != NULL); |
187 return !spill_operand_->IsIgnored(); | 189 return !spill_operand_->IsIgnored(); |
188 } | 190 } |
189 | 191 |
190 | 192 |
191 void LiveRange::SetSpillOperand(LOperand* operand) { | 193 void LiveRange::SetSpillOperand(LOperand* operand) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 } | 241 } |
240 | 242 |
241 | 243 |
242 UsePosition* LiveRange::FirstPosWithHint() const { | 244 UsePosition* LiveRange::FirstPosWithHint() const { |
243 UsePosition* pos = first_pos_; | 245 UsePosition* pos = first_pos_; |
244 while (pos != NULL && !pos->HasHint()) pos = pos->next(); | 246 while (pos != NULL && !pos->HasHint()) pos = pos->next(); |
245 return pos; | 247 return pos; |
246 } | 248 } |
247 | 249 |
248 | 250 |
249 LOperand* LiveRange::CreateAssignedOperand() { | 251 LOperand* LiveRange::CreateAssignedOperand(Zone* zone) { |
250 LOperand* op = NULL; | 252 LOperand* op = NULL; |
251 if (HasRegisterAssigned()) { | 253 if (HasRegisterAssigned()) { |
252 ASSERT(!IsSpilled()); | 254 ASSERT(!IsSpilled()); |
253 if (IsDouble()) { | 255 if (IsDouble()) { |
254 op = LDoubleRegister::Create(assigned_register()); | 256 op = LDoubleRegister::Create(assigned_register()); |
255 } else { | 257 } else { |
256 op = LRegister::Create(assigned_register()); | 258 op = LRegister::Create(assigned_register()); |
257 } | 259 } |
258 } else if (IsSpilled()) { | 260 } else if (IsSpilled()) { |
259 ASSERT(!HasRegisterAssigned()); | 261 ASSERT(!HasRegisterAssigned()); |
260 op = TopLevel()->GetSpillOperand(); | 262 op = TopLevel()->GetSpillOperand(); |
261 ASSERT(!op->IsUnallocated()); | 263 ASSERT(!op->IsUnallocated()); |
262 } else { | 264 } else { |
263 LUnallocated* unalloc = new LUnallocated(LUnallocated::NONE); | 265 LUnallocated* unalloc = new(zone) LUnallocated(LUnallocated::NONE); |
264 unalloc->set_virtual_register(id_); | 266 unalloc->set_virtual_register(id_); |
265 op = unalloc; | 267 op = unalloc; |
266 } | 268 } |
267 return op; | 269 return op; |
268 } | 270 } |
269 | 271 |
270 | 272 |
271 UseInterval* LiveRange::FirstSearchIntervalForPosition( | 273 UseInterval* LiveRange::FirstSearchIntervalForPosition( |
272 LifetimePosition position) const { | 274 LifetimePosition position) const { |
273 if (current_interval_ == NULL) return first_interval_; | 275 if (current_interval_ == NULL) return first_interval_; |
(...skipping 11 matching lines...) Expand all Loading... |
285 if (to_start_of->start().Value() > but_not_past.Value()) return; | 287 if (to_start_of->start().Value() > but_not_past.Value()) return; |
286 LifetimePosition start = | 288 LifetimePosition start = |
287 current_interval_ == NULL ? LifetimePosition::Invalid() | 289 current_interval_ == NULL ? LifetimePosition::Invalid() |
288 : current_interval_->start(); | 290 : current_interval_->start(); |
289 if (to_start_of->start().Value() > start.Value()) { | 291 if (to_start_of->start().Value() > start.Value()) { |
290 current_interval_ = to_start_of; | 292 current_interval_ = to_start_of; |
291 } | 293 } |
292 } | 294 } |
293 | 295 |
294 | 296 |
295 void LiveRange::SplitAt(LifetimePosition position, LiveRange* result) { | 297 void LiveRange::SplitAt(LifetimePosition position, |
| 298 LiveRange* result, |
| 299 Zone* zone) { |
296 ASSERT(Start().Value() < position.Value()); | 300 ASSERT(Start().Value() < position.Value()); |
297 ASSERT(result->IsEmpty()); | 301 ASSERT(result->IsEmpty()); |
298 // Find the last interval that ends before the position. If the | 302 // Find the last interval that ends before the position. If the |
299 // position is contained in one of the intervals in the chain, we | 303 // position is contained in one of the intervals in the chain, we |
300 // split that interval and use the first part. | 304 // split that interval and use the first part. |
301 UseInterval* current = FirstSearchIntervalForPosition(position); | 305 UseInterval* current = FirstSearchIntervalForPosition(position); |
302 | 306 |
303 // If the split position coincides with the beginning of a use interval | 307 // If the split position coincides with the beginning of a use interval |
304 // we need to split use positons in a special way. | 308 // we need to split use positons in a special way. |
305 bool split_at_start = false; | 309 bool split_at_start = false; |
306 | 310 |
307 if (current->start().Value() == position.Value()) { | 311 if (current->start().Value() == position.Value()) { |
308 // When splitting at start we need to locate the previous use interval. | 312 // When splitting at start we need to locate the previous use interval. |
309 current = first_interval_; | 313 current = first_interval_; |
310 } | 314 } |
311 | 315 |
312 while (current != NULL) { | 316 while (current != NULL) { |
313 if (current->Contains(position)) { | 317 if (current->Contains(position)) { |
314 current->SplitAt(position); | 318 current->SplitAt(position, zone); |
315 break; | 319 break; |
316 } | 320 } |
317 UseInterval* next = current->next(); | 321 UseInterval* next = current->next(); |
318 if (next->start().Value() >= position.Value()) { | 322 if (next->start().Value() >= position.Value()) { |
319 split_at_start = (next->start().Value() == position.Value()); | 323 split_at_start = (next->start().Value() == position.Value()); |
320 break; | 324 break; |
321 } | 325 } |
322 current = next; | 326 current = next; |
323 } | 327 } |
324 | 328 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 | 401 |
398 void LiveRange::ShortenTo(LifetimePosition start) { | 402 void LiveRange::ShortenTo(LifetimePosition start) { |
399 LAllocator::TraceAlloc("Shorten live range %d to [%d\n", id_, start.Value()); | 403 LAllocator::TraceAlloc("Shorten live range %d to [%d\n", id_, start.Value()); |
400 ASSERT(first_interval_ != NULL); | 404 ASSERT(first_interval_ != NULL); |
401 ASSERT(first_interval_->start().Value() <= start.Value()); | 405 ASSERT(first_interval_->start().Value() <= start.Value()); |
402 ASSERT(start.Value() < first_interval_->end().Value()); | 406 ASSERT(start.Value() < first_interval_->end().Value()); |
403 first_interval_->set_start(start); | 407 first_interval_->set_start(start); |
404 } | 408 } |
405 | 409 |
406 | 410 |
407 void LiveRange::EnsureInterval(LifetimePosition start, LifetimePosition end) { | 411 void LiveRange::EnsureInterval(LifetimePosition start, |
| 412 LifetimePosition end, |
| 413 Zone* zone) { |
408 LAllocator::TraceAlloc("Ensure live range %d in interval [%d %d[\n", | 414 LAllocator::TraceAlloc("Ensure live range %d in interval [%d %d[\n", |
409 id_, | 415 id_, |
410 start.Value(), | 416 start.Value(), |
411 end.Value()); | 417 end.Value()); |
412 LifetimePosition new_end = end; | 418 LifetimePosition new_end = end; |
413 while (first_interval_ != NULL && | 419 while (first_interval_ != NULL && |
414 first_interval_->start().Value() <= end.Value()) { | 420 first_interval_->start().Value() <= end.Value()) { |
415 if (first_interval_->end().Value() > end.Value()) { | 421 if (first_interval_->end().Value() > end.Value()) { |
416 new_end = first_interval_->end(); | 422 new_end = first_interval_->end(); |
417 } | 423 } |
418 first_interval_ = first_interval_->next(); | 424 first_interval_ = first_interval_->next(); |
419 } | 425 } |
420 | 426 |
421 UseInterval* new_interval = new UseInterval(start, new_end); | 427 UseInterval* new_interval = new(zone) UseInterval(start, new_end); |
422 new_interval->next_ = first_interval_; | 428 new_interval->next_ = first_interval_; |
423 first_interval_ = new_interval; | 429 first_interval_ = new_interval; |
424 if (new_interval->next() == NULL) { | 430 if (new_interval->next() == NULL) { |
425 last_interval_ = new_interval; | 431 last_interval_ = new_interval; |
426 } | 432 } |
427 } | 433 } |
428 | 434 |
429 | 435 |
430 void LiveRange::AddUseInterval(LifetimePosition start, LifetimePosition end) { | 436 void LiveRange::AddUseInterval(LifetimePosition start, |
| 437 LifetimePosition end, |
| 438 Zone* zone) { |
431 LAllocator::TraceAlloc("Add to live range %d interval [%d %d[\n", | 439 LAllocator::TraceAlloc("Add to live range %d interval [%d %d[\n", |
432 id_, | 440 id_, |
433 start.Value(), | 441 start.Value(), |
434 end.Value()); | 442 end.Value()); |
435 if (first_interval_ == NULL) { | 443 if (first_interval_ == NULL) { |
436 UseInterval* interval = new UseInterval(start, end); | 444 UseInterval* interval = new(zone) UseInterval(start, end); |
437 first_interval_ = interval; | 445 first_interval_ = interval; |
438 last_interval_ = interval; | 446 last_interval_ = interval; |
439 } else { | 447 } else { |
440 if (end.Value() == first_interval_->start().Value()) { | 448 if (end.Value() == first_interval_->start().Value()) { |
441 first_interval_->set_start(start); | 449 first_interval_->set_start(start); |
442 } else if (end.Value() < first_interval_->start().Value()) { | 450 } else if (end.Value() < first_interval_->start().Value()) { |
443 UseInterval* interval = new UseInterval(start, end); | 451 UseInterval* interval = new(zone) UseInterval(start, end); |
444 interval->set_next(first_interval_); | 452 interval->set_next(first_interval_); |
445 first_interval_ = interval; | 453 first_interval_ = interval; |
446 } else { | 454 } else { |
447 // Order of instruction's processing (see ProcessInstructions) guarantees | 455 // Order of instruction's processing (see ProcessInstructions) guarantees |
448 // that each new use interval either precedes or intersects with | 456 // that each new use interval either precedes or intersects with |
449 // last added interval. | 457 // last added interval. |
450 ASSERT(start.Value() < first_interval_->end().Value()); | 458 ASSERT(start.Value() < first_interval_->end().Value()); |
451 first_interval_->start_ = Min(start, first_interval_->start_); | 459 first_interval_->start_ = Min(start, first_interval_->start_); |
452 first_interval_->end_ = Max(end, first_interval_->end_); | 460 first_interval_->end_ = Max(end, first_interval_->end_); |
453 } | 461 } |
454 } | 462 } |
455 } | 463 } |
456 | 464 |
457 | 465 |
458 UsePosition* LiveRange::AddUsePosition(LifetimePosition pos, | 466 UsePosition* LiveRange::AddUsePosition(LifetimePosition pos, |
459 LOperand* operand) { | 467 LOperand* operand, |
| 468 Zone* zone) { |
460 LAllocator::TraceAlloc("Add to live range %d use position %d\n", | 469 LAllocator::TraceAlloc("Add to live range %d use position %d\n", |
461 id_, | 470 id_, |
462 pos.Value()); | 471 pos.Value()); |
463 UsePosition* use_pos = new UsePosition(pos, operand); | 472 UsePosition* use_pos = new(zone) UsePosition(pos, operand); |
464 UsePosition* prev = NULL; | 473 UsePosition* prev = NULL; |
465 UsePosition* current = first_pos_; | 474 UsePosition* current = first_pos_; |
466 while (current != NULL && current->pos().Value() < pos.Value()) { | 475 while (current != NULL && current->pos().Value() < pos.Value()) { |
467 prev = current; | 476 prev = current; |
468 current = current->next(); | 477 current = current->next(); |
469 } | 478 } |
470 | 479 |
471 if (prev == NULL) { | 480 if (prev == NULL) { |
472 use_pos->set_next(first_pos_); | 481 use_pos->set_next(first_pos_); |
473 first_pos_ = use_pos; | 482 first_pos_ = use_pos; |
474 } else { | 483 } else { |
475 use_pos->next_ = prev->next_; | 484 use_pos->next_ = prev->next_; |
476 prev->next_ = use_pos; | 485 prev->next_ = use_pos; |
477 } | 486 } |
478 | 487 |
479 return use_pos; | 488 return use_pos; |
480 } | 489 } |
481 | 490 |
482 | 491 |
483 void LiveRange::ConvertOperands() { | 492 void LiveRange::ConvertOperands(Zone* zone) { |
484 LOperand* op = CreateAssignedOperand(); | 493 LOperand* op = CreateAssignedOperand(zone); |
485 UsePosition* use_pos = first_pos(); | 494 UsePosition* use_pos = first_pos(); |
486 while (use_pos != NULL) { | 495 while (use_pos != NULL) { |
487 ASSERT(Start().Value() <= use_pos->pos().Value() && | 496 ASSERT(Start().Value() <= use_pos->pos().Value() && |
488 use_pos->pos().Value() <= End().Value()); | 497 use_pos->pos().Value() <= End().Value()); |
489 | 498 |
490 if (use_pos->HasOperand()) { | 499 if (use_pos->HasOperand()) { |
491 ASSERT(op->IsRegister() || op->IsDoubleRegister() || | 500 ASSERT(op->IsRegister() || op->IsDoubleRegister() || |
492 !use_pos->RequiresRegister()); | 501 !use_pos->RequiresRegister()); |
493 use_pos->operand()->ConvertTo(op->kind(), op->index()); | 502 use_pos->operand()->ConvertTo(op->kind(), op->index()); |
494 } | 503 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 AdvanceLastProcessedMarker(a, advance_last_processed_up_to); | 547 AdvanceLastProcessedMarker(a, advance_last_processed_up_to); |
539 } else { | 548 } else { |
540 b = b->next(); | 549 b = b->next(); |
541 } | 550 } |
542 } | 551 } |
543 return LifetimePosition::Invalid(); | 552 return LifetimePosition::Invalid(); |
544 } | 553 } |
545 | 554 |
546 | 555 |
547 LAllocator::LAllocator(int num_values, HGraph* graph) | 556 LAllocator::LAllocator(int num_values, HGraph* graph) |
548 : chunk_(NULL), | 557 : zone_(graph->zone()), |
549 allocation_ok_(true), | 558 chunk_(NULL), |
550 live_in_sets_(graph->blocks()->length()), | 559 live_in_sets_(graph->blocks()->length()), |
551 live_ranges_(num_values * 2), | 560 live_ranges_(num_values * 2), |
552 fixed_live_ranges_(NULL), | 561 fixed_live_ranges_(NULL), |
553 fixed_double_live_ranges_(NULL), | 562 fixed_double_live_ranges_(NULL), |
554 unhandled_live_ranges_(num_values * 2), | 563 unhandled_live_ranges_(num_values * 2), |
555 active_live_ranges_(8), | 564 active_live_ranges_(8), |
556 inactive_live_ranges_(8), | 565 inactive_live_ranges_(8), |
557 reusable_slots_(8), | 566 reusable_slots_(8), |
558 next_virtual_register_(num_values), | 567 next_virtual_register_(num_values), |
559 first_artificial_register_(num_values), | 568 first_artificial_register_(num_values), |
560 mode_(GENERAL_REGISTERS), | 569 mode_(GENERAL_REGISTERS), |
561 num_registers_(-1), | 570 num_registers_(-1), |
562 graph_(graph), | 571 graph_(graph), |
563 has_osr_entry_(false) {} | 572 has_osr_entry_(false), |
| 573 allocation_ok_(true) { } |
564 | 574 |
565 | 575 |
566 void LAllocator::InitializeLivenessAnalysis() { | 576 void LAllocator::InitializeLivenessAnalysis() { |
567 // Initialize the live_in sets for each block to NULL. | 577 // Initialize the live_in sets for each block to NULL. |
568 int block_count = graph_->blocks()->length(); | 578 int block_count = graph_->blocks()->length(); |
569 live_in_sets_.Initialize(block_count); | 579 live_in_sets_.Initialize(block_count); |
570 live_in_sets_.AddBlock(NULL, block_count); | 580 live_in_sets_.AddBlock(NULL, block_count); |
571 } | 581 } |
572 | 582 |
573 | 583 |
574 BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) { | 584 BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) { |
575 // Compute live out for the given block, except not including backward | 585 // Compute live out for the given block, except not including backward |
576 // successor edges. | 586 // successor edges. |
577 BitVector* live_out = new BitVector(next_virtual_register_); | 587 BitVector* live_out = new(zone_) BitVector(next_virtual_register_); |
578 | 588 |
579 // Process all successor blocks. | 589 // Process all successor blocks. |
580 for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) { | 590 for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) { |
581 // Add values live on entry to the successor. Note the successor's | 591 // Add values live on entry to the successor. Note the successor's |
582 // live_in will not be computed yet for backwards edges. | 592 // live_in will not be computed yet for backwards edges. |
583 HBasicBlock* successor = it.Current(); | 593 HBasicBlock* successor = it.Current(); |
584 BitVector* live_in = live_in_sets_[successor->block_id()]; | 594 BitVector* live_in = live_in_sets_[successor->block_id()]; |
585 if (live_in != NULL) live_out->Union(*live_in); | 595 if (live_in != NULL) live_out->Union(*live_in); |
586 | 596 |
587 // All phi input operands corresponding to this successor edge are live | 597 // All phi input operands corresponding to this successor edge are live |
(...skipping 17 matching lines...) Expand all Loading... |
605 // Add an interval that includes the entire block to the live range for | 615 // Add an interval that includes the entire block to the live range for |
606 // each live_out value. | 616 // each live_out value. |
607 LifetimePosition start = LifetimePosition::FromInstructionIndex( | 617 LifetimePosition start = LifetimePosition::FromInstructionIndex( |
608 block->first_instruction_index()); | 618 block->first_instruction_index()); |
609 LifetimePosition end = LifetimePosition::FromInstructionIndex( | 619 LifetimePosition end = LifetimePosition::FromInstructionIndex( |
610 block->last_instruction_index()).NextInstruction(); | 620 block->last_instruction_index()).NextInstruction(); |
611 BitVector::Iterator iterator(live_out); | 621 BitVector::Iterator iterator(live_out); |
612 while (!iterator.Done()) { | 622 while (!iterator.Done()) { |
613 int operand_index = iterator.Current(); | 623 int operand_index = iterator.Current(); |
614 LiveRange* range = LiveRangeFor(operand_index); | 624 LiveRange* range = LiveRangeFor(operand_index); |
615 range->AddUseInterval(start, end); | 625 range->AddUseInterval(start, end, zone_); |
616 iterator.Advance(); | 626 iterator.Advance(); |
617 } | 627 } |
618 } | 628 } |
619 | 629 |
620 | 630 |
621 int LAllocator::FixedDoubleLiveRangeID(int index) { | 631 int LAllocator::FixedDoubleLiveRangeID(int index) { |
622 return -index - 1 - Register::kNumAllocatableRegisters; | 632 return -index - 1 - Register::kNumAllocatableRegisters; |
623 } | 633 } |
624 | 634 |
625 | 635 |
(...skipping 21 matching lines...) Expand all Loading... |
647 } | 657 } |
648 } | 658 } |
649 return operand; | 659 return operand; |
650 } | 660 } |
651 | 661 |
652 | 662 |
653 LiveRange* LAllocator::FixedLiveRangeFor(int index) { | 663 LiveRange* LAllocator::FixedLiveRangeFor(int index) { |
654 ASSERT(index < Register::kNumAllocatableRegisters); | 664 ASSERT(index < Register::kNumAllocatableRegisters); |
655 LiveRange* result = fixed_live_ranges_[index]; | 665 LiveRange* result = fixed_live_ranges_[index]; |
656 if (result == NULL) { | 666 if (result == NULL) { |
657 result = new LiveRange(FixedLiveRangeID(index)); | 667 result = new(zone_) LiveRange(FixedLiveRangeID(index), zone_); |
658 ASSERT(result->IsFixed()); | 668 ASSERT(result->IsFixed()); |
659 result->set_assigned_register(index, GENERAL_REGISTERS); | 669 result->set_assigned_register(index, GENERAL_REGISTERS, zone_); |
660 fixed_live_ranges_[index] = result; | 670 fixed_live_ranges_[index] = result; |
661 } | 671 } |
662 return result; | 672 return result; |
663 } | 673 } |
664 | 674 |
665 | 675 |
666 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) { | 676 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) { |
667 ASSERT(index < DoubleRegister::kNumAllocatableRegisters); | 677 ASSERT(index < DoubleRegister::kNumAllocatableRegisters); |
668 LiveRange* result = fixed_double_live_ranges_[index]; | 678 LiveRange* result = fixed_double_live_ranges_[index]; |
669 if (result == NULL) { | 679 if (result == NULL) { |
670 result = new LiveRange(FixedDoubleLiveRangeID(index)); | 680 result = new(zone_) LiveRange(FixedDoubleLiveRangeID(index), zone_); |
671 ASSERT(result->IsFixed()); | 681 ASSERT(result->IsFixed()); |
672 result->set_assigned_register(index, DOUBLE_REGISTERS); | 682 result->set_assigned_register(index, DOUBLE_REGISTERS, zone_); |
673 fixed_double_live_ranges_[index] = result; | 683 fixed_double_live_ranges_[index] = result; |
674 } | 684 } |
675 return result; | 685 return result; |
676 } | 686 } |
677 | 687 |
678 | 688 |
679 LiveRange* LAllocator::LiveRangeFor(int index) { | 689 LiveRange* LAllocator::LiveRangeFor(int index) { |
680 if (index >= live_ranges_.length()) { | 690 if (index >= live_ranges_.length()) { |
681 live_ranges_.AddBlock(NULL, index - live_ranges_.length() + 1); | 691 live_ranges_.AddBlock(NULL, index - live_ranges_.length() + 1); |
682 } | 692 } |
683 LiveRange* result = live_ranges_[index]; | 693 LiveRange* result = live_ranges_[index]; |
684 if (result == NULL) { | 694 if (result == NULL) { |
685 result = new LiveRange(index); | 695 result = new(zone_) LiveRange(index, zone_); |
686 live_ranges_[index] = result; | 696 live_ranges_[index] = result; |
687 } | 697 } |
688 return result; | 698 return result; |
689 } | 699 } |
690 | 700 |
691 | 701 |
692 LGap* LAllocator::GetLastGap(HBasicBlock* block) { | 702 LGap* LAllocator::GetLastGap(HBasicBlock* block) { |
693 int last_instruction = block->last_instruction_index(); | 703 int last_instruction = block->last_instruction_index(); |
694 int index = chunk_->NearestGapPos(last_instruction); | 704 int index = chunk_->NearestGapPos(last_instruction); |
695 return GapAt(index); | 705 return GapAt(index); |
(...skipping 25 matching lines...) Expand all Loading... |
721 | 731 |
722 | 732 |
723 void LAllocator::Define(LifetimePosition position, | 733 void LAllocator::Define(LifetimePosition position, |
724 LOperand* operand, | 734 LOperand* operand, |
725 LOperand* hint) { | 735 LOperand* hint) { |
726 LiveRange* range = LiveRangeFor(operand); | 736 LiveRange* range = LiveRangeFor(operand); |
727 if (range == NULL) return; | 737 if (range == NULL) return; |
728 | 738 |
729 if (range->IsEmpty() || range->Start().Value() > position.Value()) { | 739 if (range->IsEmpty() || range->Start().Value() > position.Value()) { |
730 // Can happen if there is a definition without use. | 740 // Can happen if there is a definition without use. |
731 range->AddUseInterval(position, position.NextInstruction()); | 741 range->AddUseInterval(position, position.NextInstruction(), zone_); |
732 range->AddUsePosition(position.NextInstruction(), NULL); | 742 range->AddUsePosition(position.NextInstruction(), NULL, zone_); |
733 } else { | 743 } else { |
734 range->ShortenTo(position); | 744 range->ShortenTo(position); |
735 } | 745 } |
736 | 746 |
737 if (operand->IsUnallocated()) { | 747 if (operand->IsUnallocated()) { |
738 LUnallocated* unalloc_operand = LUnallocated::cast(operand); | 748 LUnallocated* unalloc_operand = LUnallocated::cast(operand); |
739 range->AddUsePosition(position, unalloc_operand)->set_hint(hint); | 749 range->AddUsePosition(position, unalloc_operand, zone_)->set_hint(hint); |
740 } | 750 } |
741 } | 751 } |
742 | 752 |
743 | 753 |
744 void LAllocator::Use(LifetimePosition block_start, | 754 void LAllocator::Use(LifetimePosition block_start, |
745 LifetimePosition position, | 755 LifetimePosition position, |
746 LOperand* operand, | 756 LOperand* operand, |
747 LOperand* hint) { | 757 LOperand* hint) { |
748 LiveRange* range = LiveRangeFor(operand); | 758 LiveRange* range = LiveRangeFor(operand); |
749 if (range == NULL) return; | 759 if (range == NULL) return; |
750 if (operand->IsUnallocated()) { | 760 if (operand->IsUnallocated()) { |
751 LUnallocated* unalloc_operand = LUnallocated::cast(operand); | 761 LUnallocated* unalloc_operand = LUnallocated::cast(operand); |
752 range->AddUsePosition(position, unalloc_operand)->set_hint(hint); | 762 range->AddUsePosition(position, unalloc_operand, zone_)->set_hint(hint); |
753 } | 763 } |
754 range->AddUseInterval(block_start, position); | 764 range->AddUseInterval(block_start, position, zone_); |
755 } | 765 } |
756 | 766 |
757 | 767 |
758 void LAllocator::AddConstraintsGapMove(int index, | 768 void LAllocator::AddConstraintsGapMove(int index, |
759 LOperand* from, | 769 LOperand* from, |
760 LOperand* to) { | 770 LOperand* to) { |
761 LGap* gap = GapAt(index); | 771 LGap* gap = GapAt(index); |
762 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); | 772 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); |
763 if (from->IsUnallocated()) { | 773 if (from->IsUnallocated()) { |
764 const ZoneList<LMoveOperands>* move_operands = move->move_operands(); | 774 const ZoneList<LMoveOperands>* move_operands = move->move_operands(); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 // of the instruction. | 863 // of the instruction. |
854 ASSERT(!cur_input->IsUsedAtStart()); | 864 ASSERT(!cur_input->IsUsedAtStart()); |
855 | 865 |
856 LUnallocated* input_copy = cur_input->CopyUnconstrained(); | 866 LUnallocated* input_copy = cur_input->CopyUnconstrained(); |
857 cur_input->set_virtual_register(GetVirtualRegister()); | 867 cur_input->set_virtual_register(GetVirtualRegister()); |
858 if (!AllocationOk()) return; | 868 if (!AllocationOk()) return; |
859 | 869 |
860 if (RequiredRegisterKind(input_copy->virtual_register()) == | 870 if (RequiredRegisterKind(input_copy->virtual_register()) == |
861 DOUBLE_REGISTERS) { | 871 DOUBLE_REGISTERS) { |
862 double_artificial_registers_.Add( | 872 double_artificial_registers_.Add( |
863 cur_input->virtual_register() - first_artificial_register_); | 873 cur_input->virtual_register() - first_artificial_register_, |
| 874 zone_); |
864 } | 875 } |
865 | 876 |
866 AddConstraintsGapMove(gap_index, input_copy, cur_input); | 877 AddConstraintsGapMove(gap_index, input_copy, cur_input); |
867 } | 878 } |
868 } | 879 } |
869 } | 880 } |
870 | 881 |
871 // Handle "output same as input" for second instruction. | 882 // Handle "output same as input" for second instruction. |
872 if (second != NULL && second->Output() != NULL) { | 883 if (second != NULL && second->Output() != NULL) { |
873 LUnallocated* second_output = LUnallocated::cast(second->Output()); | 884 LUnallocated* second_output = LUnallocated::cast(second->Output()); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 } | 968 } |
958 Define(curr_position, output, NULL); | 969 Define(curr_position, output, NULL); |
959 } | 970 } |
960 | 971 |
961 if (instr->IsMarkedAsCall()) { | 972 if (instr->IsMarkedAsCall()) { |
962 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { | 973 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { |
963 if (output == NULL || !output->IsRegister() || | 974 if (output == NULL || !output->IsRegister() || |
964 output->index() != i) { | 975 output->index() != i) { |
965 LiveRange* range = FixedLiveRangeFor(i); | 976 LiveRange* range = FixedLiveRangeFor(i); |
966 range->AddUseInterval(curr_position, | 977 range->AddUseInterval(curr_position, |
967 curr_position.InstructionEnd()); | 978 curr_position.InstructionEnd(), |
| 979 zone_); |
968 } | 980 } |
969 } | 981 } |
970 } | 982 } |
971 | 983 |
972 if (instr->IsMarkedAsCall() || instr->IsMarkedAsSaveDoubles()) { | 984 if (instr->IsMarkedAsCall() || instr->IsMarkedAsSaveDoubles()) { |
973 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { | 985 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { |
974 if (output == NULL || !output->IsDoubleRegister() || | 986 if (output == NULL || !output->IsDoubleRegister() || |
975 output->index() != i) { | 987 output->index() != i) { |
976 LiveRange* range = FixedDoubleLiveRangeFor(i); | 988 LiveRange* range = FixedDoubleLiveRangeFor(i); |
977 range->AddUseInterval(curr_position, | 989 range->AddUseInterval(curr_position, |
978 curr_position.InstructionEnd()); | 990 curr_position.InstructionEnd(), |
| 991 zone_); |
979 } | 992 } |
980 } | 993 } |
981 } | 994 } |
982 | 995 |
983 for (UseIterator it(instr); !it.Done(); it.Advance()) { | 996 for (UseIterator it(instr); !it.Done(); it.Advance()) { |
984 LOperand* input = it.Current(); | 997 LOperand* input = it.Current(); |
985 | 998 |
986 LifetimePosition use_pos; | 999 LifetimePosition use_pos; |
987 if (input->IsUnallocated() && | 1000 if (input->IsUnallocated() && |
988 LUnallocated::cast(input)->IsUsedAtStart()) { | 1001 LUnallocated::cast(input)->IsUsedAtStart()) { |
(...skipping 27 matching lines...) Expand all Loading... |
1016 | 1029 |
1017 index = index - 1; | 1030 index = index - 1; |
1018 } | 1031 } |
1019 } | 1032 } |
1020 | 1033 |
1021 | 1034 |
1022 void LAllocator::ResolvePhis(HBasicBlock* block) { | 1035 void LAllocator::ResolvePhis(HBasicBlock* block) { |
1023 const ZoneList<HPhi*>* phis = block->phis(); | 1036 const ZoneList<HPhi*>* phis = block->phis(); |
1024 for (int i = 0; i < phis->length(); ++i) { | 1037 for (int i = 0; i < phis->length(); ++i) { |
1025 HPhi* phi = phis->at(i); | 1038 HPhi* phi = phis->at(i); |
1026 LUnallocated* phi_operand = new LUnallocated(LUnallocated::NONE); | 1039 LUnallocated* phi_operand = new(zone_) LUnallocated(LUnallocated::NONE); |
1027 phi_operand->set_virtual_register(phi->id()); | 1040 phi_operand->set_virtual_register(phi->id()); |
1028 for (int j = 0; j < phi->OperandCount(); ++j) { | 1041 for (int j = 0; j < phi->OperandCount(); ++j) { |
1029 HValue* op = phi->OperandAt(j); | 1042 HValue* op = phi->OperandAt(j); |
1030 LOperand* operand = NULL; | 1043 LOperand* operand = NULL; |
1031 if (op->IsConstant() && op->EmitAtUses()) { | 1044 if (op->IsConstant() && op->EmitAtUses()) { |
1032 HConstant* constant = HConstant::cast(op); | 1045 HConstant* constant = HConstant::cast(op); |
1033 operand = chunk_->DefineConstantOperand(constant); | 1046 operand = chunk_->DefineConstantOperand(constant); |
1034 } else { | 1047 } else { |
1035 ASSERT(!op->EmitAtUses()); | 1048 ASSERT(!op->EmitAtUses()); |
1036 LUnallocated* unalloc = new LUnallocated(LUnallocated::ANY); | 1049 LUnallocated* unalloc = new(zone_) LUnallocated(LUnallocated::ANY); |
1037 unalloc->set_virtual_register(op->id()); | 1050 unalloc->set_virtual_register(op->id()); |
1038 operand = unalloc; | 1051 operand = unalloc; |
1039 } | 1052 } |
1040 HBasicBlock* cur_block = block->predecessors()->at(j); | 1053 HBasicBlock* cur_block = block->predecessors()->at(j); |
1041 // The gap move must be added without any special processing as in | 1054 // The gap move must be added without any special processing as in |
1042 // the AddConstraintsGapMove. | 1055 // the AddConstraintsGapMove. |
1043 chunk_->AddGapMove(cur_block->last_instruction_index() - 1, | 1056 chunk_->AddGapMove(cur_block->last_instruction_index() - 1, |
1044 operand, | 1057 operand, |
1045 phi_operand); | 1058 phi_operand); |
1046 | 1059 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 if (cur_range->CanCover(pred_end)) { | 1146 if (cur_range->CanCover(pred_end)) { |
1134 ASSERT(pred_cover == NULL); | 1147 ASSERT(pred_cover == NULL); |
1135 pred_cover = cur_range; | 1148 pred_cover = cur_range; |
1136 } | 1149 } |
1137 cur_range = cur_range->next(); | 1150 cur_range = cur_range->next(); |
1138 } | 1151 } |
1139 | 1152 |
1140 if (cur_cover->IsSpilled()) return; | 1153 if (cur_cover->IsSpilled()) return; |
1141 ASSERT(pred_cover != NULL && cur_cover != NULL); | 1154 ASSERT(pred_cover != NULL && cur_cover != NULL); |
1142 if (pred_cover != cur_cover) { | 1155 if (pred_cover != cur_cover) { |
1143 LOperand* pred_op = pred_cover->CreateAssignedOperand(); | 1156 LOperand* pred_op = pred_cover->CreateAssignedOperand(zone_); |
1144 LOperand* cur_op = cur_cover->CreateAssignedOperand(); | 1157 LOperand* cur_op = cur_cover->CreateAssignedOperand(zone_); |
1145 if (!pred_op->Equals(cur_op)) { | 1158 if (!pred_op->Equals(cur_op)) { |
1146 LGap* gap = NULL; | 1159 LGap* gap = NULL; |
1147 if (block->predecessors()->length() == 1) { | 1160 if (block->predecessors()->length() == 1) { |
1148 gap = GapAt(block->first_instruction_index()); | 1161 gap = GapAt(block->first_instruction_index()); |
1149 } else { | 1162 } else { |
1150 ASSERT(pred->end()->SecondSuccessor() == NULL); | 1163 ASSERT(pred->end()->SecondSuccessor() == NULL); |
1151 gap = GetLastGap(pred); | 1164 gap = GetLastGap(pred); |
1152 | 1165 |
1153 // We are going to insert a move before the branch instruction. | 1166 // We are going to insert a move before the branch instruction. |
1154 // Some branch instructions (e.g. loops' back edges) | 1167 // Some branch instructions (e.g. loops' back edges) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 if (!second_range->IsSpilled()) { | 1219 if (!second_range->IsSpilled()) { |
1207 // Add gap move if the two live ranges touch and there is no block | 1220 // Add gap move if the two live ranges touch and there is no block |
1208 // boundary. | 1221 // boundary. |
1209 if (first_range->End().Value() == pos.Value()) { | 1222 if (first_range->End().Value() == pos.Value()) { |
1210 bool should_insert = true; | 1223 bool should_insert = true; |
1211 if (IsBlockBoundary(pos)) { | 1224 if (IsBlockBoundary(pos)) { |
1212 should_insert = CanEagerlyResolveControlFlow(GetBlock(pos)); | 1225 should_insert = CanEagerlyResolveControlFlow(GetBlock(pos)); |
1213 } | 1226 } |
1214 if (should_insert) { | 1227 if (should_insert) { |
1215 LParallelMove* move = GetConnectingParallelMove(pos); | 1228 LParallelMove* move = GetConnectingParallelMove(pos); |
1216 LOperand* prev_operand = first_range->CreateAssignedOperand(); | 1229 LOperand* prev_operand = first_range->CreateAssignedOperand(zone_); |
1217 LOperand* cur_operand = second_range->CreateAssignedOperand(); | 1230 LOperand* cur_operand = second_range->CreateAssignedOperand(zone_); |
1218 move->AddMove(prev_operand, cur_operand); | 1231 move->AddMove(prev_operand, cur_operand); |
1219 } | 1232 } |
1220 } | 1233 } |
1221 } | 1234 } |
1222 | 1235 |
1223 first_range = second_range; | 1236 first_range = second_range; |
1224 second_range = second_range->next(); | 1237 second_range = second_range->next(); |
1225 } | 1238 } |
1226 } | 1239 } |
1227 } | 1240 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 // header. | 1323 // header. |
1311 HBasicBlock* back_edge = block->loop_information()->GetLastBackEdge(); | 1324 HBasicBlock* back_edge = block->loop_information()->GetLastBackEdge(); |
1312 BitVector::Iterator iterator(live); | 1325 BitVector::Iterator iterator(live); |
1313 LifetimePosition start = LifetimePosition::FromInstructionIndex( | 1326 LifetimePosition start = LifetimePosition::FromInstructionIndex( |
1314 block->first_instruction_index()); | 1327 block->first_instruction_index()); |
1315 LifetimePosition end = LifetimePosition::FromInstructionIndex( | 1328 LifetimePosition end = LifetimePosition::FromInstructionIndex( |
1316 back_edge->last_instruction_index()).NextInstruction(); | 1329 back_edge->last_instruction_index()).NextInstruction(); |
1317 while (!iterator.Done()) { | 1330 while (!iterator.Done()) { |
1318 int operand_index = iterator.Current(); | 1331 int operand_index = iterator.Current(); |
1319 LiveRange* range = LiveRangeFor(operand_index); | 1332 LiveRange* range = LiveRangeFor(operand_index); |
1320 range->EnsureInterval(start, end); | 1333 range->EnsureInterval(start, end, zone_); |
1321 iterator.Advance(); | 1334 iterator.Advance(); |
1322 } | 1335 } |
1323 | 1336 |
1324 for (int i = block->block_id() + 1; i <= back_edge->block_id(); ++i) { | 1337 for (int i = block->block_id() + 1; i <= back_edge->block_id(); ++i) { |
1325 live_in_sets_[i]->Union(*live); | 1338 live_in_sets_[i]->Union(*live); |
1326 } | 1339 } |
1327 } | 1340 } |
1328 | 1341 |
1329 #ifdef DEBUG | 1342 #ifdef DEBUG |
1330 if (block_id == 0) { | 1343 if (block_id == 0) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 safe_point >= range->spill_start_index()) { | 1444 safe_point >= range->spill_start_index()) { |
1432 TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n", | 1445 TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n", |
1433 range->id(), range->spill_start_index(), safe_point); | 1446 range->id(), range->spill_start_index(), safe_point); |
1434 map->RecordPointer(range->GetSpillOperand()); | 1447 map->RecordPointer(range->GetSpillOperand()); |
1435 } | 1448 } |
1436 | 1449 |
1437 if (!cur->IsSpilled()) { | 1450 if (!cur->IsSpilled()) { |
1438 TraceAlloc("Pointer in register for range %d (start at %d) " | 1451 TraceAlloc("Pointer in register for range %d (start at %d) " |
1439 "at safe point %d\n", | 1452 "at safe point %d\n", |
1440 cur->id(), cur->Start().Value(), safe_point); | 1453 cur->id(), cur->Start().Value(), safe_point); |
1441 LOperand* operand = cur->CreateAssignedOperand(); | 1454 LOperand* operand = cur->CreateAssignedOperand(zone_); |
1442 ASSERT(!operand->IsStackSlot()); | 1455 ASSERT(!operand->IsStackSlot()); |
1443 map->RecordPointer(operand); | 1456 map->RecordPointer(operand); |
1444 } | 1457 } |
1445 } | 1458 } |
1446 } | 1459 } |
1447 } | 1460 } |
1448 | 1461 |
1449 | 1462 |
1450 void LAllocator::ProcessOsrEntry() { | 1463 void LAllocator::ProcessOsrEntry() { |
1451 const ZoneList<LInstruction*>* instrs = chunk_->instructions(); | 1464 const ZoneList<LInstruction*>* instrs = chunk_->instructions(); |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1803 RegisterName(register_index), | 1816 RegisterName(register_index), |
1804 free_until_pos[register_index].Value(), | 1817 free_until_pos[register_index].Value(), |
1805 current->id(), | 1818 current->id(), |
1806 current->End().Value()); | 1819 current->End().Value()); |
1807 | 1820 |
1808 // The desired register is free until the end of the current live range. | 1821 // The desired register is free until the end of the current live range. |
1809 if (free_until_pos[register_index].Value() >= current->End().Value()) { | 1822 if (free_until_pos[register_index].Value() >= current->End().Value()) { |
1810 TraceAlloc("Assigning preferred reg %s to live range %d\n", | 1823 TraceAlloc("Assigning preferred reg %s to live range %d\n", |
1811 RegisterName(register_index), | 1824 RegisterName(register_index), |
1812 current->id()); | 1825 current->id()); |
1813 current->set_assigned_register(register_index, mode_); | 1826 current->set_assigned_register(register_index, mode_, zone_); |
1814 return true; | 1827 return true; |
1815 } | 1828 } |
1816 } | 1829 } |
1817 } | 1830 } |
1818 | 1831 |
1819 // Find the register which stays free for the longest time. | 1832 // Find the register which stays free for the longest time. |
1820 int reg = 0; | 1833 int reg = 0; |
1821 for (int i = 1; i < RegisterCount(); ++i) { | 1834 for (int i = 1; i < RegisterCount(); ++i) { |
1822 if (free_until_pos[i].Value() > free_until_pos[reg].Value()) { | 1835 if (free_until_pos[i].Value() > free_until_pos[reg].Value()) { |
1823 reg = i; | 1836 reg = i; |
(...skipping 15 matching lines...) Expand all Loading... |
1839 AddToUnhandledSorted(tail); | 1852 AddToUnhandledSorted(tail); |
1840 } | 1853 } |
1841 | 1854 |
1842 | 1855 |
1843 // Register reg is available at the range start and is free until | 1856 // Register reg is available at the range start and is free until |
1844 // the range end. | 1857 // the range end. |
1845 ASSERT(pos.Value() >= current->End().Value()); | 1858 ASSERT(pos.Value() >= current->End().Value()); |
1846 TraceAlloc("Assigning free reg %s to live range %d\n", | 1859 TraceAlloc("Assigning free reg %s to live range %d\n", |
1847 RegisterName(reg), | 1860 RegisterName(reg), |
1848 current->id()); | 1861 current->id()); |
1849 current->set_assigned_register(reg, mode_); | 1862 current->set_assigned_register(reg, mode_, zone_); |
1850 | 1863 |
1851 return true; | 1864 return true; |
1852 } | 1865 } |
1853 | 1866 |
1854 | 1867 |
1855 void LAllocator::AllocateBlockedReg(LiveRange* current) { | 1868 void LAllocator::AllocateBlockedReg(LiveRange* current) { |
1856 UsePosition* register_use = current->NextRegisterPosition(current->Start()); | 1869 UsePosition* register_use = current->NextRegisterPosition(current->Start()); |
1857 if (register_use == NULL) { | 1870 if (register_use == NULL) { |
1858 // There is no use in the current live range that requires a register. | 1871 // There is no use in the current live range that requires a register. |
1859 // We can just spill it. | 1872 // We can just spill it. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1929 current->Start(), | 1942 current->Start(), |
1930 block_pos[reg].InstructionStart()); | 1943 block_pos[reg].InstructionStart()); |
1931 AddToUnhandledSorted(tail); | 1944 AddToUnhandledSorted(tail); |
1932 } | 1945 } |
1933 | 1946 |
1934 // Register reg is not blocked for the whole range. | 1947 // Register reg is not blocked for the whole range. |
1935 ASSERT(block_pos[reg].Value() >= current->End().Value()); | 1948 ASSERT(block_pos[reg].Value() >= current->End().Value()); |
1936 TraceAlloc("Assigning blocked reg %s to live range %d\n", | 1949 TraceAlloc("Assigning blocked reg %s to live range %d\n", |
1937 RegisterName(reg), | 1950 RegisterName(reg), |
1938 current->id()); | 1951 current->id()); |
1939 current->set_assigned_register(reg, mode_); | 1952 current->set_assigned_register(reg, mode_, zone_); |
1940 | 1953 |
1941 // This register was not free. Thus we need to find and spill | 1954 // This register was not free. Thus we need to find and spill |
1942 // parts of active and inactive live regions that use the same register | 1955 // parts of active and inactive live regions that use the same register |
1943 // at the same lifetime positions as current. | 1956 // at the same lifetime positions as current. |
1944 SplitAndSpillIntersecting(current); | 1957 SplitAndSpillIntersecting(current); |
1945 } | 1958 } |
1946 | 1959 |
1947 | 1960 |
1948 void LAllocator::SplitAndSpillIntersecting(LiveRange* current) { | 1961 void LAllocator::SplitAndSpillIntersecting(LiveRange* current) { |
1949 ASSERT(current->HasRegisterAssigned()); | 1962 ASSERT(current->HasRegisterAssigned()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 | 2009 |
1997 if (pos.Value() <= range->Start().Value()) return range; | 2010 if (pos.Value() <= range->Start().Value()) return range; |
1998 | 2011 |
1999 // We can't properly connect liveranges if split occured at the end | 2012 // We can't properly connect liveranges if split occured at the end |
2000 // of control instruction. | 2013 // of control instruction. |
2001 ASSERT(pos.IsInstructionStart() || | 2014 ASSERT(pos.IsInstructionStart() || |
2002 !chunk_->instructions()->at(pos.InstructionIndex())->IsControl()); | 2015 !chunk_->instructions()->at(pos.InstructionIndex())->IsControl()); |
2003 | 2016 |
2004 LiveRange* result = LiveRangeFor(GetVirtualRegister()); | 2017 LiveRange* result = LiveRangeFor(GetVirtualRegister()); |
2005 if (!AllocationOk()) return NULL; | 2018 if (!AllocationOk()) return NULL; |
2006 range->SplitAt(pos, result); | 2019 range->SplitAt(pos, result, zone_); |
2007 return result; | 2020 return result; |
2008 } | 2021 } |
2009 | 2022 |
2010 | 2023 |
2011 LiveRange* LAllocator::SplitBetween(LiveRange* range, | 2024 LiveRange* LAllocator::SplitBetween(LiveRange* range, |
2012 LifetimePosition start, | 2025 LifetimePosition start, |
2013 LifetimePosition end) { | 2026 LifetimePosition end) { |
2014 ASSERT(!range->IsFixed()); | 2027 ASSERT(!range->IsFixed()); |
2015 TraceAlloc("Splitting live range %d in position between [%d, %d]\n", | 2028 TraceAlloc("Splitting live range %d in position between [%d, %d]\n", |
2016 range->id(), | 2029 range->id(), |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2095 void LAllocator::Spill(LiveRange* range) { | 2108 void LAllocator::Spill(LiveRange* range) { |
2096 ASSERT(!range->IsSpilled()); | 2109 ASSERT(!range->IsSpilled()); |
2097 TraceAlloc("Spilling live range %d\n", range->id()); | 2110 TraceAlloc("Spilling live range %d\n", range->id()); |
2098 LiveRange* first = range->TopLevel(); | 2111 LiveRange* first = range->TopLevel(); |
2099 | 2112 |
2100 if (!first->HasAllocatedSpillOperand()) { | 2113 if (!first->HasAllocatedSpillOperand()) { |
2101 LOperand* op = TryReuseSpillSlot(range); | 2114 LOperand* op = TryReuseSpillSlot(range); |
2102 if (op == NULL) op = chunk_->GetNextSpillSlot(mode_ == DOUBLE_REGISTERS); | 2115 if (op == NULL) op = chunk_->GetNextSpillSlot(mode_ == DOUBLE_REGISTERS); |
2103 first->SetSpillOperand(op); | 2116 first->SetSpillOperand(op); |
2104 } | 2117 } |
2105 range->MakeSpilled(); | 2118 range->MakeSpilled(zone_); |
2106 } | 2119 } |
2107 | 2120 |
2108 | 2121 |
2109 int LAllocator::RegisterCount() const { | 2122 int LAllocator::RegisterCount() const { |
2110 return num_registers_; | 2123 return num_registers_; |
2111 } | 2124 } |
2112 | 2125 |
2113 | 2126 |
2114 #ifdef DEBUG | 2127 #ifdef DEBUG |
2115 | 2128 |
2116 | 2129 |
2117 void LAllocator::Verify() const { | 2130 void LAllocator::Verify() const { |
2118 for (int i = 0; i < live_ranges()->length(); ++i) { | 2131 for (int i = 0; i < live_ranges()->length(); ++i) { |
2119 LiveRange* current = live_ranges()->at(i); | 2132 LiveRange* current = live_ranges()->at(i); |
2120 if (current != NULL) current->Verify(); | 2133 if (current != NULL) current->Verify(); |
2121 } | 2134 } |
2122 } | 2135 } |
2123 | 2136 |
2124 | 2137 |
2125 #endif | 2138 #endif |
2126 | 2139 |
2127 | 2140 |
2128 } } // namespace v8::internal | 2141 } } // namespace v8::internal |
OLD | NEW |