| 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 |