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

Unified Diff: src/compiler/register-allocator.cc

Issue 1426943010: [turbofan] Spill rsi and rdi in their existing locations. (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/compiler/register-allocator-verifier.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/register-allocator.cc
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
index 0dc76000f784771856dd10e29daedddb3b2ad27e..49ae35b63da63e85a1be1a478182782f5b719286 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -671,13 +671,13 @@ unsigned LiveRange::GetSize() {
}
-struct TopLevelLiveRange::SpillAtDefinitionList : ZoneObject {
- SpillAtDefinitionList(int gap_index, InstructionOperand* operand,
- SpillAtDefinitionList* next)
+struct TopLevelLiveRange::SpillMoveInsertionList : ZoneObject {
+ SpillMoveInsertionList(int gap_index, InstructionOperand* operand,
+ SpillMoveInsertionList* next)
: gap_index(gap_index), operand(operand), next(next) {}
const int gap_index;
InstructionOperand* const operand;
- SpillAtDefinitionList* const next;
+ SpillMoveInsertionList* const next;
};
@@ -687,12 +687,13 @@ TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineType machine_type)
last_child_id_(0),
splintered_from_(nullptr),
spill_operand_(nullptr),
- spills_at_definition_(nullptr),
+ spill_move_insertion_locations_(nullptr),
spilled_in_deferred_blocks_(false),
spill_start_index_(kMaxInt),
last_child_(this),
last_pos_(nullptr),
- splinter_(nullptr) {
+ splinter_(nullptr),
+ has_preassigned_slot_(false) {
bits_ |= SpillTypeField::encode(SpillType::kNoSpillType);
}
@@ -704,11 +705,11 @@ int TopLevelLiveRange::debug_virt_reg() const {
#endif
-void TopLevelLiveRange::SpillAtDefinition(Zone* zone, int gap_index,
- InstructionOperand* operand) {
+void TopLevelLiveRange::RecordSpillLocation(Zone* zone, int gap_index,
+ InstructionOperand* operand) {
DCHECK(HasNoSpillType());
- spills_at_definition_ = new (zone)
- SpillAtDefinitionList(gap_index, operand, spills_at_definition_);
+ spill_move_insertion_locations_ = new (zone) SpillMoveInsertionList(
+ gap_index, operand, spill_move_insertion_locations_);
}
@@ -754,7 +755,7 @@ void TopLevelLiveRange::MarkSpilledInDeferredBlock(
spill_start_index_ = -1;
spilled_in_deferred_blocks_ = true;
- spills_at_definition_ = nullptr;
+ spill_move_insertion_locations_ = nullptr;
}
@@ -794,25 +795,26 @@ bool TopLevelLiveRange::TryCommitSpillInDeferredBlock(
}
-void TopLevelLiveRange::CommitSpillsAtDefinition(InstructionSequence* sequence,
- const InstructionOperand& op,
- bool might_be_duplicated) {
- DCHECK_IMPLIES(op.IsConstant(), spills_at_definition_ == nullptr);
+void TopLevelLiveRange::CommitSpillMoves(InstructionSequence* sequence,
+ const InstructionOperand& op,
+ bool might_be_duplicated) {
+ DCHECK_IMPLIES(op.IsConstant(), spill_move_insertion_locations() == nullptr);
auto zone = sequence->zone();
- for (auto to_spill = spills_at_definition_; to_spill != nullptr;
+ for (auto to_spill = spill_move_insertion_locations(); to_spill != nullptr;
to_spill = to_spill->next) {
auto instr = sequence->InstructionAt(to_spill->gap_index);
auto move = instr->GetOrCreateParallelMove(Instruction::START, zone);
// Skip insertion if it's possible that the move exists already as a
// constraint move from a fixed output register to a slot.
- if (might_be_duplicated) {
+ if (might_be_duplicated || has_preassigned_slot()) {
bool found = false;
for (auto move_op : *move) {
if (move_op->IsEliminated()) continue;
if (move_op->source().Equals(*to_spill->operand) &&
move_op->destination().Equals(op)) {
found = true;
+ if (has_preassigned_slot()) move_op->Eliminate();
break;
}
}
@@ -1609,7 +1611,7 @@ void ConstraintBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
const InstructionBlock* successor = code()->InstructionBlockAt(succ);
DCHECK(successor->PredecessorCount() == 1);
int gap_index = successor->first_instruction_index();
- range->SpillAtDefinition(allocation_zone(), gap_index, output);
+ range->RecordSpillLocation(allocation_zone(), gap_index, output);
range->SetSpillStartIndex(gap_index);
}
}
@@ -1642,6 +1644,17 @@ void ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
int output_vreg = first_output->virtual_register();
UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
bool is_tagged = code()->IsReference(output_vreg);
+ if (first_output->HasSecondaryStorage()) {
+ range->MarkHasPreassignedSlot();
+ InstructionOperand* spill_op = AllocatedOperand::New(
+ data()->code_zone(), LocationOperand::LocationKind::STACK_SLOT,
+ range->machine_type(), first_output->GetSecondaryStorage());
+ range->RecordSpillLocation(allocation_zone(), instr_index + 1,
+ first_output);
+ range->SetSpillOperand(spill_op);
+ range->SetSpillStartIndex(instr_index + 1);
+ assigned = true;
+ }
AllocateFixed(first_output, instr_index, is_tagged);
// This value is produced on the stack, we never need to spill it.
@@ -1658,8 +1671,8 @@ void ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
// Make sure we add a gap move for spilling (if we have not done
// so already).
if (!assigned) {
- range->SpillAtDefinition(allocation_zone(), instr_index + 1,
- first_output);
+ range->RecordSpillLocation(allocation_zone(), instr_index + 1,
+ first_output);
range->SetSpillStartIndex(instr_index + 1);
}
}
@@ -1744,7 +1757,7 @@ void ConstraintBuilder::ResolvePhis(const InstructionBlock* block) {
}
auto live_range = data()->GetOrCreateLiveRangeFor(phi_vreg);
int gap_index = block->first_instruction_index();
- live_range->SpillAtDefinition(allocation_zone(), gap_index, &output);
+ live_range->RecordSpillLocation(allocation_zone(), gap_index, &output);
live_range->SetSpillStartIndex(gap_index);
// We use the phi-ness of some nodes in some later heuristics.
live_range->set_is_phi(true);
@@ -2959,7 +2972,7 @@ void SpillSlotLocator::LocateSpillSlots() {
}
}
} else {
- auto spills = range->spills_at_definition();
+ auto spills = range->spill_move_insertion_locations();
DCHECK_NOT_NULL(spills);
for (; spills != nullptr; spills = spills->next) {
code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
@@ -3032,7 +3045,7 @@ void OperandAssigner::CommitAssignment() {
spill_operand)) {
// Spill at definition if the range isn't spilled only in deferred
// blocks.
- top_range->CommitSpillsAtDefinition(
+ top_range->CommitSpillMoves(
data()->code(), spill_operand,
top_range->has_slot_use() || top_range->spilled());
}
@@ -3073,6 +3086,7 @@ void ReferenceMapPopulator::PopulateReferenceMaps() {
if (!data()->IsReference(range)) continue;
// Skip empty live ranges.
if (range->IsEmpty()) continue;
+ if (range->has_preassigned_slot()) continue;
// Find the extent of the range and its children.
int start = range->Start().ToInstructionIndex();
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/compiler/register-allocator-verifier.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698