Commit ec839eb9 authored by Yolanda Chen's avatar Yolanda Chen Committed by Commit Bot

[regalloc] Do not spill uses that are constrained to move to register in...

[regalloc] Do not spill uses that are constrained to move to register in backwards spilling heuristics

For uses that are moved to registers, they are not beneficial for backwards spilling as it will introduce memory loads from stack to register.

Bug: chromium:1066869, chromium:1063831
Change-Id: I562d22336b6607a8f7286fc65dbf5b95a941a130
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2172052Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Yolanda Chen <yolanda.chen@intel.com>
Cr-Commit-Position: refs/heads/master@{#67765}
parent d04ab197
...@@ -519,6 +519,16 @@ UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial( ...@@ -519,6 +519,16 @@ UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial(
return prev; return prev;
} }
UsePosition* LiveRange::NextUsePositionSpillDetrimental(
LifetimePosition start) const {
UsePosition* pos = NextUsePosition(start);
while (pos != nullptr && pos->type() != UsePositionType::kRequiresRegister &&
!pos->SpillDetrimental()) {
pos = pos->next();
}
return pos;
}
UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) const { UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) const {
UsePosition* pos = NextUsePosition(start); UsePosition* pos = NextUsePosition(start);
while (pos != nullptr && pos->type() != UsePositionType::kRequiresRegister) { while (pos != nullptr && pos->type() != UsePositionType::kRequiresRegister) {
...@@ -2424,6 +2434,15 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block, ...@@ -2424,6 +2434,15 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
if (from.IsUnallocated()) { if (from.IsUnallocated()) {
live->Add(UnallocatedOperand::cast(from).virtual_register()); live->Add(UnallocatedOperand::cast(from).virtual_register());
} }
// When the value is moved to a register to meet input constraints,
// we should consider this value use similar as a register use in the
// backward spilling heuristics, even though this value use is not
// register benefical at the AllocateBlockedReg stage.
if (to.IsAnyRegister() ||
(to.IsUnallocated() &&
UnallocatedOperand::cast(&to)->HasRegisterPolicy())) {
from_use->set_spill_detrimental();
}
// Resolve use position hints just created. // Resolve use position hints just created.
if (to_use != nullptr && from_use != nullptr) { if (to_use != nullptr && from_use != nullptr) {
to_use->ResolveHint(from_use); to_use->ResolveHint(from_use);
...@@ -3039,14 +3058,17 @@ LifetimePosition RegisterAllocator::FindOptimalSpillingPos( ...@@ -3039,14 +3058,17 @@ LifetimePosition RegisterAllocator::FindOptimalSpillingPos(
LiveRange* check_use = live_at_header; LiveRange* check_use = live_at_header;
for (; check_use != nullptr && check_use->Start() < pos; for (; check_use != nullptr && check_use->Start() < pos;
check_use = check_use->next()) { check_use = check_use->next()) {
UsePosition* next_use = check_use->NextRegisterPosition(loop_start); // If we find a use for which spilling is detrimental, don't spill
// at the loop header
UsePosition* next_use =
check_use->NextUsePositionSpillDetrimental(loop_start);
// UsePosition at the end of a UseInterval may // UsePosition at the end of a UseInterval may
// have the same value as the start of next range. // have the same value as the start of next range.
if (next_use != nullptr && next_use->pos() <= pos) { if (next_use != nullptr && next_use->pos() <= pos) {
return pos; return pos;
} }
} }
// No register use inside the loop before the pos. // No register beneficial use inside the loop before the pos.
*begin_spill_out = live_at_header; *begin_spill_out = live_at_header;
pos = loop_start; pos = loop_start;
break; break;
......
...@@ -459,6 +459,10 @@ class V8_EXPORT_PRIVATE UsePosition final ...@@ -459,6 +459,10 @@ class V8_EXPORT_PRIVATE UsePosition final
bool RegisterIsBeneficial() const { bool RegisterIsBeneficial() const {
return RegisterBeneficialField::decode(flags_); return RegisterBeneficialField::decode(flags_);
} }
bool SpillDetrimental() const {
return SpillDetrimentalField::decode(flags_);
}
UsePositionType type() const { return TypeField::decode(flags_); } UsePositionType type() const { return TypeField::decode(flags_); }
void set_type(UsePositionType type, bool register_beneficial); void set_type(UsePositionType type, bool register_beneficial);
...@@ -471,6 +475,9 @@ class V8_EXPORT_PRIVATE UsePosition final ...@@ -471,6 +475,9 @@ class V8_EXPORT_PRIVATE UsePosition final
void set_assigned_register(int register_code) { void set_assigned_register(int register_code) {
flags_ = AssignedRegisterField::update(flags_, register_code); flags_ = AssignedRegisterField::update(flags_, register_code);
} }
void set_spill_detrimental() {
flags_ = SpillDetrimentalField::update(flags_, true);
}
UsePositionHintType hint_type() const { UsePositionHintType hint_type() const {
return HintTypeField::decode(flags_); return HintTypeField::decode(flags_);
...@@ -489,6 +496,7 @@ class V8_EXPORT_PRIVATE UsePosition final ...@@ -489,6 +496,7 @@ class V8_EXPORT_PRIVATE UsePosition final
using HintTypeField = base::BitField<UsePositionHintType, 2, 3>; using HintTypeField = base::BitField<UsePositionHintType, 2, 3>;
using RegisterBeneficialField = base::BitField<bool, 5, 1>; using RegisterBeneficialField = base::BitField<bool, 5, 1>;
using AssignedRegisterField = base::BitField<int32_t, 6, 6>; using AssignedRegisterField = base::BitField<int32_t, 6, 6>;
using SpillDetrimentalField = base::BitField<int32_t, 12, 1>;
InstructionOperand* const operand_; InstructionOperand* const operand_;
void* hint_; void* hint_;
...@@ -584,6 +592,10 @@ class V8_EXPORT_PRIVATE LiveRange : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -584,6 +592,10 @@ class V8_EXPORT_PRIVATE LiveRange : public NON_EXPORTED_BASE(ZoneObject) {
UsePosition* PreviousUsePositionRegisterIsBeneficial( UsePosition* PreviousUsePositionRegisterIsBeneficial(
LifetimePosition start) const; LifetimePosition start) const;
// Returns use position for which spilling is detrimental in this live
// range and which follows both start and last processed use position
UsePosition* NextUsePositionSpillDetrimental(LifetimePosition start) const;
// Can this live range be spilled at this position. // Can this live range be spilled at this position.
bool CanBeSpilled(LifetimePosition pos) const; bool CanBeSpilled(LifetimePosition pos) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment