| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 } | 289 } |
| 290 | 290 |
| 291 | 291 |
| 292 void LiveRange::SplitAt(LifetimePosition position, LiveRange* result) { | 292 void LiveRange::SplitAt(LifetimePosition position, LiveRange* result) { |
| 293 ASSERT(Start().Value() < position.Value()); | 293 ASSERT(Start().Value() < position.Value()); |
| 294 ASSERT(result->IsEmpty()); | 294 ASSERT(result->IsEmpty()); |
| 295 // Find the last interval that ends before the position. If the | 295 // Find the last interval that ends before the position. If the |
| 296 // position is contained in one of the intervals in the chain, we | 296 // position is contained in one of the intervals in the chain, we |
| 297 // split that interval and use the first part. | 297 // split that interval and use the first part. |
| 298 UseInterval* current = FirstSearchIntervalForPosition(position); | 298 UseInterval* current = FirstSearchIntervalForPosition(position); |
| 299 |
| 300 // If the split position coincides with the beginning of a use interval |
| 301 // we need to split use positons in a special way. |
| 302 bool split_at_start = false; |
| 303 |
| 299 while (current != NULL) { | 304 while (current != NULL) { |
| 300 if (current->Contains(position)) { | 305 if (current->Contains(position)) { |
| 301 current->SplitAt(position); | 306 current->SplitAt(position); |
| 302 break; | 307 break; |
| 303 } | 308 } |
| 304 UseInterval* next = current->next(); | 309 UseInterval* next = current->next(); |
| 305 if (next->start().Value() >= position.Value()) break; | 310 if (next->start().Value() >= position.Value()) { |
| 311 split_at_start = (next->start().Value() == position.Value()); |
| 312 break; |
| 313 } |
| 306 current = next; | 314 current = next; |
| 307 } | 315 } |
| 308 | 316 |
| 309 // Partition original use intervals to the two live ranges. | 317 // Partition original use intervals to the two live ranges. |
| 310 UseInterval* before = current; | 318 UseInterval* before = current; |
| 311 UseInterval* after = before->next(); | 319 UseInterval* after = before->next(); |
| 312 result->last_interval_ = (last_interval_ == before) | 320 result->last_interval_ = (last_interval_ == before) |
| 313 ? after // Only interval in the range after split. | 321 ? after // Only interval in the range after split. |
| 314 : last_interval_; // Last interval of the original range. | 322 : last_interval_; // Last interval of the original range. |
| 315 result->first_interval_ = after; | 323 result->first_interval_ = after; |
| 316 last_interval_ = before; | 324 last_interval_ = before; |
| 317 | 325 |
| 318 // Find the last use position before the split and the first use | 326 // Find the last use position before the split and the first use |
| 319 // position after it. | 327 // position after it. |
| 320 UsePosition* use_after = first_pos_; | 328 UsePosition* use_after = first_pos_; |
| 321 UsePosition* use_before = NULL; | 329 UsePosition* use_before = NULL; |
| 322 while (use_after != NULL && use_after->pos().Value() <= position.Value()) { | 330 if (split_at_start) { |
| 323 use_before = use_after; | 331 // The split position coincides with the beginning of a use interval (the |
| 324 use_after = use_after->next(); | 332 // end of a lifetime hole). Use at this position should be attributed to |
| 333 // the split child because split child owns use interval covering it. |
| 334 while (use_after != NULL && use_after->pos().Value() < position.Value()) { |
| 335 use_before = use_after; |
| 336 use_after = use_after->next(); |
| 337 } |
| 338 } else { |
| 339 while (use_after != NULL && use_after->pos().Value() <= position.Value()) { |
| 340 use_before = use_after; |
| 341 use_after = use_after->next(); |
| 342 } |
| 325 } | 343 } |
| 326 | 344 |
| 327 // Partition original use positions to the two live ranges. | 345 // Partition original use positions to the two live ranges. |
| 328 if (use_before != NULL) { | 346 if (use_before != NULL) { |
| 329 use_before->next_ = NULL; | 347 use_before->next_ = NULL; |
| 330 } else { | 348 } else { |
| 331 first_pos_ = NULL; | 349 first_pos_ = NULL; |
| 332 } | 350 } |
| 333 result->first_pos_ = use_after; | 351 result->first_pos_ = use_after; |
| 334 | 352 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 UseInterval* a = FirstSearchIntervalForPosition(b->start()); | 519 UseInterval* a = FirstSearchIntervalForPosition(b->start()); |
| 502 while (a != NULL && b != NULL) { | 520 while (a != NULL && b != NULL) { |
| 503 if (a->start().Value() > other->End().Value()) break; | 521 if (a->start().Value() > other->End().Value()) break; |
| 504 if (b->start().Value() > End().Value()) break; | 522 if (b->start().Value() > End().Value()) break; |
| 505 LifetimePosition cur_intersection = a->Intersect(b); | 523 LifetimePosition cur_intersection = a->Intersect(b); |
| 506 if (cur_intersection.IsValid()) { | 524 if (cur_intersection.IsValid()) { |
| 507 return cur_intersection; | 525 return cur_intersection; |
| 508 } | 526 } |
| 509 if (a->start().Value() < b->start().Value()) { | 527 if (a->start().Value() < b->start().Value()) { |
| 510 a = a->next(); | 528 a = a->next(); |
| 511 if (a == NULL && a->start().Value() > other->End().Value()) break; | 529 if (a == NULL || a->start().Value() > other->End().Value()) break; |
| 512 AdvanceLastProcessedMarker(a, advance_last_processed_up_to); | 530 AdvanceLastProcessedMarker(a, advance_last_processed_up_to); |
| 513 } else { | 531 } else { |
| 514 b = b->next(); | 532 b = b->next(); |
| 515 } | 533 } |
| 516 } | 534 } |
| 517 return LifetimePosition::Invalid(); | 535 return LifetimePosition::Invalid(); |
| 518 } | 536 } |
| 519 | 537 |
| 520 | 538 |
| 521 void LAllocator::InitializeLivenessAnalysis() { | 539 void LAllocator::InitializeLivenessAnalysis() { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 } | 578 } |
| 561 | 579 |
| 562 | 580 |
| 563 void LAllocator::AddInitialIntervals(HBasicBlock* block, | 581 void LAllocator::AddInitialIntervals(HBasicBlock* block, |
| 564 BitVector* live_out) { | 582 BitVector* live_out) { |
| 565 // Add an interval that includes the entire block to the live range for | 583 // Add an interval that includes the entire block to the live range for |
| 566 // each live_out value. | 584 // each live_out value. |
| 567 LifetimePosition start = LifetimePosition::FromInstructionIndex( | 585 LifetimePosition start = LifetimePosition::FromInstructionIndex( |
| 568 block->first_instruction_index()); | 586 block->first_instruction_index()); |
| 569 LifetimePosition end = LifetimePosition::FromInstructionIndex( | 587 LifetimePosition end = LifetimePosition::FromInstructionIndex( |
| 570 block->last_instruction_index()); | 588 block->last_instruction_index()).NextInstruction(); |
| 571 BitVector::Iterator iterator(live_out); | 589 BitVector::Iterator iterator(live_out); |
| 572 while (!iterator.Done()) { | 590 while (!iterator.Done()) { |
| 573 int operand_index = iterator.Current(); | 591 int operand_index = iterator.Current(); |
| 574 LiveRange* range = LiveRangeFor(operand_index); | 592 LiveRange* range = LiveRangeFor(operand_index); |
| 575 if (!range->IsEmpty() && | 593 range->AddUseInterval(start, end); |
| 576 range->Start().Value() == end.NextInstruction().Value()) { | |
| 577 range->AddUseInterval(start, end.NextInstruction()); | |
| 578 } else { | |
| 579 range->AddUseInterval(start, end); | |
| 580 } | |
| 581 iterator.Advance(); | 594 iterator.Advance(); |
| 582 } | 595 } |
| 583 } | 596 } |
| 584 | 597 |
| 585 | 598 |
| 586 int LAllocator::FixedDoubleLiveRangeID(int index) { | 599 int LAllocator::FixedDoubleLiveRangeID(int index) { |
| 587 return -index - 1 - Register::kNumAllocatableRegisters; | 600 return -index - 1 - Register::kNumAllocatableRegisters; |
| 588 } | 601 } |
| 589 | 602 |
| 590 | 603 |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 LOperand* temp = summary->TempAt(i); | 966 LOperand* temp = summary->TempAt(i); |
| 954 if (summary->IsCall()) { | 967 if (summary->IsCall()) { |
| 955 if (temp->IsRegister()) continue; | 968 if (temp->IsRegister()) continue; |
| 956 if (temp->IsUnallocated()) { | 969 if (temp->IsUnallocated()) { |
| 957 LUnallocated* temp_unalloc = LUnallocated::cast(temp); | 970 LUnallocated* temp_unalloc = LUnallocated::cast(temp); |
| 958 if (temp_unalloc->HasFixedPolicy()) { | 971 if (temp_unalloc->HasFixedPolicy()) { |
| 959 continue; | 972 continue; |
| 960 } | 973 } |
| 961 } | 974 } |
| 962 } | 975 } |
| 963 Use(block_start_position, curr_position, temp, NULL); | 976 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); |
| 964 Define(curr_position.PrevInstruction(), temp, NULL); | 977 Define(curr_position, temp, NULL); |
| 965 } | 978 } |
| 966 } | 979 } |
| 967 } | 980 } |
| 968 | 981 |
| 969 index = index - 1; | 982 index = index - 1; |
| 970 } | 983 } |
| 971 } | 984 } |
| 972 | 985 |
| 973 | 986 |
| 974 void LAllocator::ResolvePhis(HBasicBlock* block) { | 987 void LAllocator::ResolvePhis(HBasicBlock* block) { |
| (...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1807 // Register reg is available at the range start but becomes blocked before | 1820 // Register reg is available at the range start but becomes blocked before |
| 1808 // the range end. Split current at position where it becomes blocked. | 1821 // the range end. Split current at position where it becomes blocked. |
| 1809 LiveRange* tail = SplitAt(current, pos); | 1822 LiveRange* tail = SplitAt(current, pos); |
| 1810 AddToUnhandledSorted(tail); | 1823 AddToUnhandledSorted(tail); |
| 1811 } | 1824 } |
| 1812 | 1825 |
| 1813 | 1826 |
| 1814 // Register reg is available at the range start and is free until | 1827 // Register reg is available at the range start and is free until |
| 1815 // the range end. | 1828 // the range end. |
| 1816 ASSERT(pos.Value() >= current->End().Value()); | 1829 ASSERT(pos.Value() >= current->End().Value()); |
| 1817 TraceAlloc("Assigning reg %s to live range %d\n", | 1830 TraceAlloc("Assigning free reg %s to live range %d\n", |
| 1818 RegisterName(reg), | 1831 RegisterName(reg), |
| 1819 current->id()); | 1832 current->id()); |
| 1820 current->set_assigned_register(reg, mode_); | 1833 current->set_assigned_register(reg, mode_); |
| 1821 | 1834 |
| 1822 return true; | 1835 return true; |
| 1823 } | 1836 } |
| 1824 | 1837 |
| 1825 | 1838 |
| 1826 void LAllocator::AllocateBlockedReg(LiveRange* current) { | 1839 void LAllocator::AllocateBlockedReg(LiveRange* current) { |
| 1827 UsePosition* register_use = current->NextRegisterPosition(current->Start()); | 1840 UsePosition* register_use = current->NextRegisterPosition(current->Start()); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1897 // Register becomes blocked before the current range end. Split before that | 1910 // Register becomes blocked before the current range end. Split before that |
| 1898 // position. | 1911 // position. |
| 1899 LiveRange* tail = SplitBetween(current, | 1912 LiveRange* tail = SplitBetween(current, |
| 1900 current->Start(), | 1913 current->Start(), |
| 1901 block_pos[reg].InstructionStart()); | 1914 block_pos[reg].InstructionStart()); |
| 1902 AddToUnhandledSorted(tail); | 1915 AddToUnhandledSorted(tail); |
| 1903 } | 1916 } |
| 1904 | 1917 |
| 1905 // Register reg is not blocked for the whole range. | 1918 // Register reg is not blocked for the whole range. |
| 1906 ASSERT(block_pos[reg].Value() >= current->End().Value()); | 1919 ASSERT(block_pos[reg].Value() >= current->End().Value()); |
| 1907 TraceAlloc("Assigning reg %s to live range %d\n", | 1920 TraceAlloc("Assigning blocked reg %s to live range %d\n", |
| 1908 RegisterName(reg), | 1921 RegisterName(reg), |
| 1909 current->id()); | 1922 current->id()); |
| 1910 current->set_assigned_register(reg, mode_); | 1923 current->set_assigned_register(reg, mode_); |
| 1911 | 1924 |
| 1912 // This register was not free. Thus we need to find and spill | 1925 // This register was not free. Thus we need to find and spill |
| 1913 // parts of active and inactive live regions that use the same register | 1926 // parts of active and inactive live regions that use the same register |
| 1914 // at the same lifetime positions as current. | 1927 // at the same lifetime positions as current. |
| 1915 SplitAndSpillIntersecting(current); | 1928 SplitAndSpillIntersecting(current); |
| 1916 } | 1929 } |
| 1917 | 1930 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2094 LiveRange* current = live_ranges()->at(i); | 2107 LiveRange* current = live_ranges()->at(i); |
| 2095 if (current != NULL) current->Verify(); | 2108 if (current != NULL) current->Verify(); |
| 2096 } | 2109 } |
| 2097 } | 2110 } |
| 2098 | 2111 |
| 2099 | 2112 |
| 2100 #endif | 2113 #endif |
| 2101 | 2114 |
| 2102 | 2115 |
| 2103 } } // namespace v8::internal | 2116 } } // namespace v8::internal |
| OLD | NEW |