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(
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* pos = NextUsePosition(start);
while (pos != nullptr && pos->type() != UsePositionType::kRequiresRegister) {
......@@ -2424,6 +2434,15 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
if (from.IsUnallocated()) {
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.
if (to_use != nullptr && from_use != nullptr) {
to_use->ResolveHint(from_use);
......@@ -3039,14 +3058,17 @@ LifetimePosition RegisterAllocator::FindOptimalSpillingPos(
LiveRange* check_use = live_at_header;
for (; check_use != nullptr && check_use->Start() < pos;
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
// have the same value as the start of next range.
if (next_use != nullptr && next_use->pos() <= 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;
pos = loop_start;
break;
......
......@@ -459,6 +459,10 @@ class V8_EXPORT_PRIVATE UsePosition final
bool RegisterIsBeneficial() const {
return RegisterBeneficialField::decode(flags_);
}
bool SpillDetrimental() const {
return SpillDetrimentalField::decode(flags_);
}
UsePositionType type() const { return TypeField::decode(flags_); }
void set_type(UsePositionType type, bool register_beneficial);
......@@ -471,6 +475,9 @@ class V8_EXPORT_PRIVATE UsePosition final
void set_assigned_register(int register_code) {
flags_ = AssignedRegisterField::update(flags_, register_code);
}
void set_spill_detrimental() {
flags_ = SpillDetrimentalField::update(flags_, true);
}
UsePositionHintType hint_type() const {
return HintTypeField::decode(flags_);
......@@ -489,6 +496,7 @@ class V8_EXPORT_PRIVATE UsePosition final
using HintTypeField = base::BitField<UsePositionHintType, 2, 3>;
using RegisterBeneficialField = base::BitField<bool, 5, 1>;
using AssignedRegisterField = base::BitField<int32_t, 6, 6>;
using SpillDetrimentalField = base::BitField<int32_t, 12, 1>;
InstructionOperand* const operand_;
void* hint_;
......@@ -584,6 +592,10 @@ class V8_EXPORT_PRIVATE LiveRange : public NON_EXPORTED_BASE(ZoneObject) {
UsePosition* PreviousUsePositionRegisterIsBeneficial(
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.
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