| OLD | NEW |
| 1 // Copyright 2010 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 ASSERT(result->IsEmpty()); | 296 ASSERT(result->IsEmpty()); |
| 297 // Find the last interval that ends before the position. If the | 297 // Find the last interval that ends before the position. If the |
| 298 // position is contained in one of the intervals in the chain, we | 298 // position is contained in one of the intervals in the chain, we |
| 299 // split that interval and use the first part. | 299 // split that interval and use the first part. |
| 300 UseInterval* current = FirstSearchIntervalForPosition(position); | 300 UseInterval* current = FirstSearchIntervalForPosition(position); |
| 301 | 301 |
| 302 // If the split position coincides with the beginning of a use interval | 302 // If the split position coincides with the beginning of a use interval |
| 303 // we need to split use positons in a special way. | 303 // we need to split use positons in a special way. |
| 304 bool split_at_start = false; | 304 bool split_at_start = false; |
| 305 | 305 |
| 306 if (current->start().Value() == position.Value()) { |
| 307 // When splitting at start we need to locate the previous use interval. |
| 308 current = first_interval_; |
| 309 } |
| 310 |
| 306 while (current != NULL) { | 311 while (current != NULL) { |
| 307 if (current->Contains(position)) { | 312 if (current->Contains(position)) { |
| 308 current->SplitAt(position); | 313 current->SplitAt(position); |
| 309 break; | 314 break; |
| 310 } | 315 } |
| 311 UseInterval* next = current->next(); | 316 UseInterval* next = current->next(); |
| 312 if (next->start().Value() >= position.Value()) { | 317 if (next->start().Value() >= position.Value()) { |
| 313 split_at_start = (next->start().Value() == position.Value()); | 318 split_at_start = (next->start().Value() == position.Value()); |
| 314 break; | 319 break; |
| 315 } | 320 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 345 } | 350 } |
| 346 | 351 |
| 347 // Partition original use positions to the two live ranges. | 352 // Partition original use positions to the two live ranges. |
| 348 if (use_before != NULL) { | 353 if (use_before != NULL) { |
| 349 use_before->next_ = NULL; | 354 use_before->next_ = NULL; |
| 350 } else { | 355 } else { |
| 351 first_pos_ = NULL; | 356 first_pos_ = NULL; |
| 352 } | 357 } |
| 353 result->first_pos_ = use_after; | 358 result->first_pos_ = use_after; |
| 354 | 359 |
| 360 // Discard cached iteration state. It might be pointing |
| 361 // to the use that no longer belongs to this live range. |
| 362 last_processed_use_ = NULL; |
| 363 current_interval_ = NULL; |
| 364 |
| 355 // Link the new live range in the chain before any of the other | 365 // Link the new live range in the chain before any of the other |
| 356 // ranges linked from the range before the split. | 366 // ranges linked from the range before the split. |
| 357 result->parent_ = (parent_ == NULL) ? this : parent_; | 367 result->parent_ = (parent_ == NULL) ? this : parent_; |
| 358 result->next_ = next_; | 368 result->next_ = next_; |
| 359 next_ = result; | 369 next_ = result; |
| 360 | 370 |
| 361 #ifdef DEBUG | 371 #ifdef DEBUG |
| 362 Verify(); | 372 Verify(); |
| 363 result->Verify(); | 373 result->Verify(); |
| 364 #endif | 374 #endif |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 live_in_sets_.AddBlock(NULL, block_count); | 568 live_in_sets_.AddBlock(NULL, block_count); |
| 559 } | 569 } |
| 560 | 570 |
| 561 | 571 |
| 562 BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) { | 572 BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) { |
| 563 // Compute live out for the given block, except not including backward | 573 // Compute live out for the given block, except not including backward |
| 564 // successor edges. | 574 // successor edges. |
| 565 BitVector* live_out = new BitVector(next_virtual_register_); | 575 BitVector* live_out = new BitVector(next_virtual_register_); |
| 566 | 576 |
| 567 // Process all successor blocks. | 577 // Process all successor blocks. |
| 568 HBasicBlock* successor = block->end()->FirstSuccessor(); | 578 for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) { |
| 569 while (successor != NULL) { | |
| 570 // Add values live on entry to the successor. Note the successor's | 579 // Add values live on entry to the successor. Note the successor's |
| 571 // live_in will not be computed yet for backwards edges. | 580 // live_in will not be computed yet for backwards edges. |
| 581 HBasicBlock* successor = it.Current(); |
| 572 BitVector* live_in = live_in_sets_[successor->block_id()]; | 582 BitVector* live_in = live_in_sets_[successor->block_id()]; |
| 573 if (live_in != NULL) live_out->Union(*live_in); | 583 if (live_in != NULL) live_out->Union(*live_in); |
| 574 | 584 |
| 575 // All phi input operands corresponding to this successor edge are live | 585 // All phi input operands corresponding to this successor edge are live |
| 576 // out from this block. | 586 // out from this block. |
| 577 int index = successor->PredecessorIndexOf(block); | 587 int index = successor->PredecessorIndexOf(block); |
| 578 const ZoneList<HPhi*>* phis = successor->phis(); | 588 const ZoneList<HPhi*>* phis = successor->phis(); |
| 579 for (int i = 0; i < phis->length(); ++i) { | 589 for (int i = 0; i < phis->length(); ++i) { |
| 580 HPhi* phi = phis->at(i); | 590 HPhi* phi = phis->at(i); |
| 581 if (!phi->OperandAt(index)->IsConstant()) { | 591 if (!phi->OperandAt(index)->IsConstant()) { |
| 582 live_out->Add(phi->OperandAt(index)->id()); | 592 live_out->Add(phi->OperandAt(index)->id()); |
| 583 } | 593 } |
| 584 } | 594 } |
| 585 | |
| 586 // Check if we are done with second successor. | |
| 587 if (successor == block->end()->SecondSuccessor()) break; | |
| 588 | |
| 589 successor = block->end()->SecondSuccessor(); | |
| 590 } | 595 } |
| 591 | 596 |
| 592 return live_out; | 597 return live_out; |
| 593 } | 598 } |
| 594 | 599 |
| 595 | 600 |
| 596 void LAllocator::AddInitialIntervals(HBasicBlock* block, | 601 void LAllocator::AddInitialIntervals(HBasicBlock* block, |
| 597 BitVector* live_out) { | 602 BitVector* live_out) { |
| 598 // Add an interval that includes the entire block to the live range for | 603 // Add an interval that includes the entire block to the live range for |
| 599 // each live_out value. | 604 // each live_out value. |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 } | 788 } |
| 784 } | 789 } |
| 785 } | 790 } |
| 786 | 791 |
| 787 | 792 |
| 788 void LAllocator::MeetConstraintsBetween(LInstruction* first, | 793 void LAllocator::MeetConstraintsBetween(LInstruction* first, |
| 789 LInstruction* second, | 794 LInstruction* second, |
| 790 int gap_index) { | 795 int gap_index) { |
| 791 // Handle fixed temporaries. | 796 // Handle fixed temporaries. |
| 792 if (first != NULL) { | 797 if (first != NULL) { |
| 793 for (TempIterator it(first); it.HasNext(); it.Advance()) { | 798 for (TempIterator it(first); !it.Done(); it.Advance()) { |
| 794 LUnallocated* temp = LUnallocated::cast(it.Next()); | 799 LUnallocated* temp = LUnallocated::cast(it.Current()); |
| 795 if (temp->HasFixedPolicy()) { | 800 if (temp->HasFixedPolicy()) { |
| 796 AllocateFixed(temp, gap_index - 1, false); | 801 AllocateFixed(temp, gap_index - 1, false); |
| 797 } | 802 } |
| 798 } | 803 } |
| 799 } | 804 } |
| 800 | 805 |
| 801 // Handle fixed output operand. | 806 // Handle fixed output operand. |
| 802 if (first != NULL && first->Output() != NULL) { | 807 if (first != NULL && first->Output() != NULL) { |
| 803 LUnallocated* first_output = LUnallocated::cast(first->Output()); | 808 LUnallocated* first_output = LUnallocated::cast(first->Output()); |
| 804 LiveRange* range = LiveRangeFor(first_output->VirtualRegister()); | 809 LiveRange* range = LiveRangeFor(first_output->VirtualRegister()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 825 // Thus it should be inserted to a lifetime position corresponding to | 830 // Thus it should be inserted to a lifetime position corresponding to |
| 826 // the instruction end. | 831 // the instruction end. |
| 827 LGap* gap = GapAt(gap_index); | 832 LGap* gap = GapAt(gap_index); |
| 828 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE); | 833 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE); |
| 829 move->AddMove(first_output, range->GetSpillOperand()); | 834 move->AddMove(first_output, range->GetSpillOperand()); |
| 830 } | 835 } |
| 831 } | 836 } |
| 832 | 837 |
| 833 // Handle fixed input operands of second instruction. | 838 // Handle fixed input operands of second instruction. |
| 834 if (second != NULL) { | 839 if (second != NULL) { |
| 835 for (UseIterator it(second); it.HasNext(); it.Advance()) { | 840 for (UseIterator it(second); !it.Done(); it.Advance()) { |
| 836 LUnallocated* cur_input = LUnallocated::cast(it.Next()); | 841 LUnallocated* cur_input = LUnallocated::cast(it.Current()); |
| 837 if (cur_input->HasFixedPolicy()) { | 842 if (cur_input->HasFixedPolicy()) { |
| 838 LUnallocated* input_copy = cur_input->CopyUnconstrained(); | 843 LUnallocated* input_copy = cur_input->CopyUnconstrained(); |
| 839 bool is_tagged = HasTaggedValue(cur_input->VirtualRegister()); | 844 bool is_tagged = HasTaggedValue(cur_input->VirtualRegister()); |
| 840 AllocateFixed(cur_input, gap_index + 1, is_tagged); | 845 AllocateFixed(cur_input, gap_index + 1, is_tagged); |
| 841 AddConstraintsGapMove(gap_index, input_copy, cur_input); | 846 AddConstraintsGapMove(gap_index, input_copy, cur_input); |
| 842 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) { | 847 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) { |
| 843 // The live range of writable input registers always goes until the end | 848 // The live range of writable input registers always goes until the end |
| 844 // of the instruction. | 849 // of the instruction. |
| 845 ASSERT(!cur_input->IsUsedAtStart()); | 850 ASSERT(!cur_input->IsUsedAtStart()); |
| 846 | 851 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { | 966 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { |
| 962 if (output == NULL || !output->IsDoubleRegister() || | 967 if (output == NULL || !output->IsDoubleRegister() || |
| 963 output->index() != i) { | 968 output->index() != i) { |
| 964 LiveRange* range = FixedDoubleLiveRangeFor(i); | 969 LiveRange* range = FixedDoubleLiveRangeFor(i); |
| 965 range->AddUseInterval(curr_position, | 970 range->AddUseInterval(curr_position, |
| 966 curr_position.InstructionEnd()); | 971 curr_position.InstructionEnd()); |
| 967 } | 972 } |
| 968 } | 973 } |
| 969 } | 974 } |
| 970 | 975 |
| 971 for (UseIterator it(instr); it.HasNext(); it.Advance()) { | 976 for (UseIterator it(instr); !it.Done(); it.Advance()) { |
| 972 LOperand* input = it.Next(); | 977 LOperand* input = it.Current(); |
| 973 | 978 |
| 974 LifetimePosition use_pos; | 979 LifetimePosition use_pos; |
| 975 if (input->IsUnallocated() && | 980 if (input->IsUnallocated() && |
| 976 LUnallocated::cast(input)->IsUsedAtStart()) { | 981 LUnallocated::cast(input)->IsUsedAtStart()) { |
| 977 use_pos = curr_position; | 982 use_pos = curr_position; |
| 978 } else { | 983 } else { |
| 979 use_pos = curr_position.InstructionEnd(); | 984 use_pos = curr_position.InstructionEnd(); |
| 980 } | 985 } |
| 981 | 986 |
| 982 Use(block_start_position, use_pos, input, NULL); | 987 Use(block_start_position, use_pos, input, NULL); |
| 983 if (input->IsUnallocated()) live->Add(input->VirtualRegister()); | 988 if (input->IsUnallocated()) live->Add(input->VirtualRegister()); |
| 984 } | 989 } |
| 985 | 990 |
| 986 for (TempIterator it(instr); it.HasNext(); it.Advance()) { | 991 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
| 987 LOperand* temp = it.Next(); | 992 LOperand* temp = it.Current(); |
| 988 if (instr->IsMarkedAsCall()) { | 993 if (instr->IsMarkedAsCall()) { |
| 989 if (temp->IsRegister()) continue; | 994 if (temp->IsRegister()) continue; |
| 990 if (temp->IsUnallocated()) { | 995 if (temp->IsUnallocated()) { |
| 991 LUnallocated* temp_unalloc = LUnallocated::cast(temp); | 996 LUnallocated* temp_unalloc = LUnallocated::cast(temp); |
| 992 if (temp_unalloc->HasFixedPolicy()) { | 997 if (temp_unalloc->HasFixedPolicy()) { |
| 993 continue; | 998 continue; |
| 994 } | 999 } |
| 995 } | 1000 } |
| 996 } | 1001 } |
| 997 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); | 1002 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1012 LUnallocated* phi_operand = new LUnallocated(LUnallocated::NONE); | 1017 LUnallocated* phi_operand = new LUnallocated(LUnallocated::NONE); |
| 1013 phi_operand->set_virtual_register(phi->id()); | 1018 phi_operand->set_virtual_register(phi->id()); |
| 1014 for (int j = 0; j < phi->OperandCount(); ++j) { | 1019 for (int j = 0; j < phi->OperandCount(); ++j) { |
| 1015 HValue* op = phi->OperandAt(j); | 1020 HValue* op = phi->OperandAt(j); |
| 1016 LOperand* operand = NULL; | 1021 LOperand* operand = NULL; |
| 1017 if (op->IsConstant() && op->EmitAtUses()) { | 1022 if (op->IsConstant() && op->EmitAtUses()) { |
| 1018 HConstant* constant = HConstant::cast(op); | 1023 HConstant* constant = HConstant::cast(op); |
| 1019 operand = chunk_->DefineConstantOperand(constant); | 1024 operand = chunk_->DefineConstantOperand(constant); |
| 1020 } else { | 1025 } else { |
| 1021 ASSERT(!op->EmitAtUses()); | 1026 ASSERT(!op->EmitAtUses()); |
| 1022 LUnallocated* unalloc = new LUnallocated(LUnallocated::NONE); | 1027 LUnallocated* unalloc = new LUnallocated(LUnallocated::ANY); |
| 1023 unalloc->set_virtual_register(op->id()); | 1028 unalloc->set_virtual_register(op->id()); |
| 1024 operand = unalloc; | 1029 operand = unalloc; |
| 1025 } | 1030 } |
| 1026 HBasicBlock* cur_block = block->predecessors()->at(j); | 1031 HBasicBlock* cur_block = block->predecessors()->at(j); |
| 1027 // The gap move must be added without any special processing as in | 1032 // The gap move must be added without any special processing as in |
| 1028 // the AddConstraintsGapMove. | 1033 // the AddConstraintsGapMove. |
| 1029 chunk_->AddGapMove(cur_block->last_instruction_index() - 1, | 1034 chunk_->AddGapMove(cur_block->last_instruction_index() - 1, |
| 1030 operand, | 1035 operand, |
| 1031 phi_operand); | 1036 phi_operand); |
| 1032 | 1037 |
| (...skipping 1086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2119 LiveRange* current = live_ranges()->at(i); | 2124 LiveRange* current = live_ranges()->at(i); |
| 2120 if (current != NULL) current->Verify(); | 2125 if (current != NULL) current->Verify(); |
| 2121 } | 2126 } |
| 2122 } | 2127 } |
| 2123 | 2128 |
| 2124 | 2129 |
| 2125 #endif | 2130 #endif |
| 2126 | 2131 |
| 2127 | 2132 |
| 2128 } } // namespace v8::internal | 2133 } } // namespace v8::internal |
| OLD | NEW |