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

Side by Side Diff: src/compiler/register-allocator.cc

Issue 460623002: Revert "More lazy deoptimization in Turbofan (binops, loads/stores)" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/compiler/x64/linkage-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/register-allocator.h" 5 #include "src/compiler/register-allocator.h"
6 6
7 #include "src/compiler/linkage.h" 7 #include "src/compiler/linkage.h"
8 #include "src/hydrogen.h" 8 #include "src/hydrogen.h"
9 #include "src/string-stream.h" 9 #include "src/string-stream.h"
10 10
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 for (int i = start; i <= end; ++i) { 737 for (int i = start; i <= end; ++i) {
738 if (code()->IsGapAt(i)) { 738 if (code()->IsGapAt(i)) {
739 Instruction* instr = NULL; 739 Instruction* instr = NULL;
740 Instruction* prev_instr = NULL; 740 Instruction* prev_instr = NULL;
741 if (i < end) instr = InstructionAt(i + 1); 741 if (i < end) instr = InstructionAt(i + 1);
742 if (i > start) prev_instr = InstructionAt(i - 1); 742 if (i > start) prev_instr = InstructionAt(i - 1);
743 MeetConstraintsBetween(prev_instr, instr, i); 743 MeetConstraintsBetween(prev_instr, instr, i);
744 if (!AllocationOk()) return; 744 if (!AllocationOk()) return;
745 } 745 }
746 } 746 }
747
748 // Meet register constraints for the instruction in the end.
749 if (!code()->IsGapAt(end)) {
750 MeetRegisterConstraintsForLastInstructionInBlock(block);
751 }
752 }
753
754
755 void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
756 BasicBlock* block) {
757 int end = block->last_instruction_index();
758 Instruction* last_instruction = InstructionAt(end);
759 for (size_t i = 0; i < last_instruction->OutputCount(); i++) {
760 InstructionOperand* output_operand = last_instruction->OutputAt(i);
761 DCHECK(!output_operand->IsConstant());
762 UnallocatedOperand* output = UnallocatedOperand::cast(output_operand);
763 int output_vreg = output->virtual_register();
764 LiveRange* range = LiveRangeFor(output_vreg);
765 bool assigned = false;
766 if (output->HasFixedPolicy()) {
767 AllocateFixed(output, -1, false);
768 // This value is produced on the stack, we never need to spill it.
769 if (output->IsStackSlot()) {
770 range->SetSpillOperand(output);
771 range->SetSpillStartIndex(end);
772 assigned = true;
773 }
774
775 BasicBlock::Successors successors = block->successors();
776 for (BasicBlock::Successors::iterator succ = successors.begin();
777 succ != successors.end(); ++succ) {
778 DCHECK((*succ)->PredecessorCount() == 1);
779 int gap_index = (*succ)->first_instruction_index() + 1;
780 DCHECK(code()->IsGapAt(gap_index));
781
782 // Create an unconstrained operand for the same virtual register
783 // and insert a gap move from the fixed output to the operand.
784 UnallocatedOperand* output_copy =
785 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY);
786 output_copy->set_virtual_register(output_vreg);
787
788 code()->AddGapMove(gap_index, output, output_copy);
789 }
790 }
791
792 if (!assigned) {
793 BasicBlock::Successors successors = block->successors();
794 for (BasicBlock::Successors::iterator succ = successors.begin();
795 succ != successors.end(); ++succ) {
796 DCHECK((*succ)->PredecessorCount() == 1);
797 int gap_index = (*succ)->first_instruction_index() + 1;
798 range->SetSpillStartIndex(gap_index);
799
800 // This move to spill operand is not a real use. Liveness analysis
801 // and splitting of live ranges do not account for it.
802 // Thus it should be inserted to a lifetime position corresponding to
803 // the instruction end.
804 GapInstruction* gap = code()->GapAt(gap_index);
805 ParallelMove* move =
806 gap->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone());
807 move->AddMove(output, range->GetSpillOperand(), code_zone());
808 }
809 }
810 }
811 } 747 }
812 748
813 749
814 void RegisterAllocator::MeetConstraintsBetween(Instruction* first, 750 void RegisterAllocator::MeetConstraintsBetween(Instruction* first,
815 Instruction* second, 751 Instruction* second,
816 int gap_index) { 752 int gap_index) {
817 if (first != NULL) { 753 if (first != NULL) {
818 // Handle fixed temporaries. 754 // Handle fixed temporaries.
819 for (size_t i = 0; i < first->TempCount(); i++) { 755 for (size_t i = 0; i < first->TempCount(); i++) {
820 UnallocatedOperand* temp = UnallocatedOperand::cast(first->TempAt(i)); 756 UnallocatedOperand* temp = UnallocatedOperand::cast(first->TempAt(i));
(...skipping 22 matching lines...) Expand all
843 779
844 // This value is produced on the stack, we never need to spill it. 780 // This value is produced on the stack, we never need to spill it.
845 if (first_output->IsStackSlot()) { 781 if (first_output->IsStackSlot()) {
846 range->SetSpillOperand(first_output); 782 range->SetSpillOperand(first_output);
847 range->SetSpillStartIndex(gap_index - 1); 783 range->SetSpillStartIndex(gap_index - 1);
848 assigned = true; 784 assigned = true;
849 } 785 }
850 code()->AddGapMove(gap_index, first_output, output_copy); 786 code()->AddGapMove(gap_index, first_output, output_copy);
851 } 787 }
852 788
853 // Make sure we add a gap move for spilling (if we have not done
854 // so already).
855 if (!assigned) { 789 if (!assigned) {
856 range->SetSpillStartIndex(gap_index); 790 range->SetSpillStartIndex(gap_index);
857 791
858 // This move to spill operand is not a real use. Liveness analysis 792 // This move to spill operand is not a real use. Liveness analysis
859 // and splitting of live ranges do not account for it. 793 // and splitting of live ranges do not account for it.
860 // Thus it should be inserted to a lifetime position corresponding to 794 // Thus it should be inserted to a lifetime position corresponding to
861 // the instruction end. 795 // the instruction end.
862 GapInstruction* gap = code()->GapAt(gap_index); 796 GapInstruction* gap = code()->GapAt(gap_index);
863 ParallelMove* move = 797 ParallelMove* move =
864 gap->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone()); 798 gap->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone());
(...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after
2223 allocator_zone_start_allocation_size_; 2157 allocator_zone_start_allocation_size_;
2224 isolate()->GetTStatistics()->SaveTiming(name(), base::TimeDelta(), size); 2158 isolate()->GetTStatistics()->SaveTiming(name(), base::TimeDelta(), size);
2225 } 2159 }
2226 #ifdef DEBUG 2160 #ifdef DEBUG
2227 if (allocator_ != NULL) allocator_->Verify(); 2161 if (allocator_ != NULL) allocator_->Verify();
2228 #endif 2162 #endif
2229 } 2163 }
2230 } 2164 }
2231 } 2165 }
2232 } // namespace v8::internal::compiler 2166 } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/compiler/x64/linkage-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698