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

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

Issue 1408183007: [turbofan] Setup frames as needed. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | 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/base/adapters.h" 5 #include "src/base/adapters.h"
6 #include "src/compiler/linkage.h" 6 #include "src/compiler/linkage.h"
7 #include "src/compiler/register-allocator.h" 7 #include "src/compiler/register-allocator.h"
8 #include "src/string-stream.h" 8 #include "src/string-stream.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 705
706 706
707 void TopLevelLiveRange::SpillAtDefinition(Zone* zone, int gap_index, 707 void TopLevelLiveRange::SpillAtDefinition(Zone* zone, int gap_index,
708 InstructionOperand* operand) { 708 InstructionOperand* operand) {
709 DCHECK(HasNoSpillType()); 709 DCHECK(HasNoSpillType());
710 spills_at_definition_ = new (zone) 710 spills_at_definition_ = new (zone)
711 SpillAtDefinitionList(gap_index, operand, spills_at_definition_); 711 SpillAtDefinitionList(gap_index, operand, spills_at_definition_);
712 } 712 }
713 713
714 714
715 bool TopLevelLiveRange::TryCommitSpillInDeferredBlock( 715 void TopLevelLiveRange::MarkSpilledInDeferredBlock(
716 InstructionSequence* code, const InstructionOperand& spill_operand) { 716 const InstructionSequence* code) {
717 if (!FLAG_turbo_preprocess_ranges || IsEmpty() || HasNoSpillType() || 717 if (!FLAG_turbo_preprocess_ranges || IsEmpty() || HasNoSpillType() ||
718 spill_operand.IsConstant() || spill_operand.IsImmediate()) { 718 !HasSpillRange()) {
719 return false; 719 return;
720 } 720 }
721 721
722 int count = 0; 722 int count = 0;
723 for (const LiveRange* child = this; child != nullptr; child = child->next()) { 723 for (const LiveRange* child = this; child != nullptr; child = child->next()) {
724 int first_instr = child->Start().ToInstructionIndex(); 724 int first_instr = child->Start().ToInstructionIndex();
725 725
726 // If the range starts at instruction end, the first instruction index is 726 // If the range starts at instruction end, the first instruction index is
727 // the next one. 727 // the next one.
728 if (!child->Start().IsGapPosition() && !child->Start().IsStart()) { 728 if (!child->Start().IsGapPosition() && !child->Start().IsStart()) {
729 ++first_instr; 729 ++first_instr;
730 } 730 }
731 731
732 // We only look at where the range starts. It doesn't matter where it ends: 732 // We only look at where the range starts. It doesn't matter where it ends:
733 // if it ends past this block, then either there is a phi there already, 733 // if it ends past this block, then either there is a phi there already,
734 // or ResolveControlFlow will adapt the last instruction gap of this block 734 // or ResolveControlFlow will adapt the last instruction gap of this block
735 // as if there were a phi. In either case, data flow will be correct. 735 // as if there were a phi. In either case, data flow will be correct.
736 const InstructionBlock* block = code->GetInstructionBlock(first_instr); 736 const InstructionBlock* block = code->GetInstructionBlock(first_instr);
737 737
738 // If we have slot uses in a subrange, bail out, because we need the value 738 // If we have slot uses in a subrange, bail out, because we need the value
739 // on the stack before that use. 739 // on the stack before that use.
740 bool has_slot_use = child->NextSlotPosition(child->Start()) != nullptr; 740 bool has_slot_use = child->NextSlotPosition(child->Start()) != nullptr;
741 if (!block->IsDeferred()) { 741 if (!block->IsDeferred()) {
742 if (child->spilled() || has_slot_use) { 742 if (child->spilled() || has_slot_use) {
743 TRACE( 743 TRACE(
744 "Live Range %d must be spilled at definition: found a " 744 "Live Range %d must be spilled at definition: found a "
745 "slot-requiring non-deferred child range %d.\n", 745 "slot-requiring non-deferred child range %d.\n",
746 TopLevel()->vreg(), child->relative_id()); 746 TopLevel()->vreg(), child->relative_id());
747 return false; 747 return;
748 } 748 }
749 } else { 749 } else {
750 if (child->spilled() || has_slot_use) ++count; 750 if (child->spilled() || has_slot_use) ++count;
751 } 751 }
752 } 752 }
753 if (count == 0) return false; 753 if (count == 0) return;
754 754
755 spill_start_index_ = -1; 755 spill_start_index_ = -1;
756 spilled_in_deferred_blocks_ = true; 756 spilled_in_deferred_blocks_ = true;
757 spills_at_definition_ = nullptr;
758 }
759
760
761 bool TopLevelLiveRange::TryCommitSpillInDeferredBlock(
762 InstructionSequence* code, const InstructionOperand& spill_operand) {
763 if (!IsSpilledOnlyInDeferredBlocks()) return false;
757 764
758 TRACE("Live Range %d will be spilled only in deferred blocks.\n", vreg()); 765 TRACE("Live Range %d will be spilled only in deferred blocks.\n", vreg());
759 // If we have ranges that aren't spilled but require the operand on the stack, 766 // If we have ranges that aren't spilled but require the operand on the stack,
760 // make sure we insert the spill. 767 // make sure we insert the spill.
761 for (const LiveRange* child = this; child != nullptr; child = child->next()) { 768 for (const LiveRange* child = this; child != nullptr; child = child->next()) {
762 if (!child->spilled() && 769 if (!child->spilled() &&
763 child->NextSlotPosition(child->Start()) != nullptr) { 770 child->NextSlotPosition(child->Start()) != nullptr) {
764 auto instr = code->InstructionAt(child->Start().ToInstructionIndex()); 771 auto instr = code->InstructionAt(child->Start().ToInstructionIndex());
765 // Insert spill at the end to let live range connections happen at START. 772 // Insert spill at the end to let live range connections happen at START.
766 auto move = 773 auto move =
(...skipping 2188 matching lines...) Expand 10 before | Expand all | Expand 10 after
2955 SpillSlotLocator::SpillSlotLocator(RegisterAllocationData* data) 2962 SpillSlotLocator::SpillSlotLocator(RegisterAllocationData* data)
2956 : data_(data) {} 2963 : data_(data) {}
2957 2964
2958 2965
2959 void SpillSlotLocator::LocateSpillSlots() { 2966 void SpillSlotLocator::LocateSpillSlots() {
2960 auto code = data()->code(); 2967 auto code = data()->code();
2961 for (TopLevelLiveRange* range : data()->live_ranges()) { 2968 for (TopLevelLiveRange* range : data()->live_ranges()) {
2962 if (range == nullptr || range->IsEmpty()) continue; 2969 if (range == nullptr || range->IsEmpty()) continue;
2963 // We care only about ranges which spill in the frame. 2970 // We care only about ranges which spill in the frame.
2964 if (!range->HasSpillRange()) continue; 2971 if (!range->HasSpillRange()) continue;
2965 auto spills = range->spills_at_definition(); 2972 range->MarkSpilledInDeferredBlock(data()->code());
2966 DCHECK_NOT_NULL(spills); 2973 if (range->IsSpilledOnlyInDeferredBlocks()) {
2967 for (; spills != nullptr; spills = spills->next) { 2974 for (LiveRange* child = range; child != nullptr; child = child->next()) {
2968 code->GetInstructionBlock(spills->gap_index)->mark_needs_frame(); 2975 if (child->spilled()) {
2976 code->GetInstructionBlock(child->Start().ToInstructionIndex())
2977 ->mark_needs_frame();
2978 }
2979 }
2980 } else {
2981 auto spills = range->spills_at_definition();
2982 DCHECK_NOT_NULL(spills);
2983 for (; spills != nullptr; spills = spills->next) {
2984 code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
2985 }
2969 } 2986 }
2970 } 2987 }
2971 } 2988 }
2972 2989
2973 2990
2974 OperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {} 2991 OperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {}
2975 2992
2976 2993
2977 void OperandAssigner::AssignSpillSlots() { 2994 void OperandAssigner::AssignSpillSlots() {
2978 ZoneVector<SpillRange*>& spill_ranges = data()->spill_ranges(); 2995 ZoneVector<SpillRange*>& spill_ranges = data()->spill_ranges();
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
3443 auto eliminate = moves->PrepareInsertAfter(move); 3460 auto eliminate = moves->PrepareInsertAfter(move);
3444 to_insert.push_back(move); 3461 to_insert.push_back(move);
3445 if (eliminate != nullptr) to_eliminate.push_back(eliminate); 3462 if (eliminate != nullptr) to_eliminate.push_back(eliminate);
3446 } 3463 }
3447 } 3464 }
3448 3465
3449 3466
3450 } // namespace compiler 3467 } // namespace compiler
3451 } // namespace internal 3468 } // namespace internal
3452 } // namespace v8 3469 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698