Commit 4f719cca authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

Revert "[regalloc] Introduce deferred fixed ranges"

This reverts commit b1769313.

Reason for revert: Flag access breaks TSAN (not an issue with this
CL as such, but we need to revert to re-open the tree).

Original change's description:
> [regalloc] Introduce deferred fixed ranges
> 
> Fixed ranges are used to express register constraints in the
> allocator. This change splits these fixed ranges into one for
> normal code and deferred code. The former are handeled as before
> whereas the latter are only made visible while allocating
> registers for deferred code.
> 
> This prevents forward looking decisions in normal code to be
> impacted by register constraints from deferred code.
> 
> Change-Id: I67d562bb41166194e62765d5ab051bc961054fc7
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1477742
> Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#60322}

TBR=jarin@chromium.org,sigurds@chromium.org,herhut@chromium.org

Change-Id: I5675a96acf0b5e5f7d63c60a742d2971b6d0d34d
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1530803Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60324}
parent a6d32847
...@@ -651,11 +651,7 @@ std::ostream& operator<<(std::ostream& os, ...@@ -651,11 +651,7 @@ std::ostream& operator<<(std::ostream& os,
const InstructionSequence* code = printable_block.code_; const InstructionSequence* code = printable_block.code_;
os << "B" << block->rpo_number(); os << "B" << block->rpo_number();
if (block->ao_number().IsValid()) { os << ": AO#" << block->ao_number();
os << ": AO#" << block->ao_number();
} else {
os << ": AO#?";
}
if (block->IsDeferred()) os << " (deferred)"; if (block->IsDeferred()) os << " (deferred)";
if (!block->needs_frame()) os << " (no frame)"; if (!block->needs_frame()) os << " (no frame)";
if (block->must_construct_frame()) os << " (construct frame)"; if (block->must_construct_frame()) os << " (construct frame)";
......
This diff is collapsed.
...@@ -467,12 +467,11 @@ class V8_EXPORT_PRIVATE LiveRange : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -467,12 +467,11 @@ class V8_EXPORT_PRIVATE LiveRange : public NON_EXPORTED_BASE(ZoneObject) {
void VerifyIntervals() const; void VerifyIntervals() const;
typedef BitField<bool, 0, 1> SpilledField; typedef BitField<bool, 0, 1> SpilledField;
// Bits (1,7[ are used by TopLevelLiveRange. // Bits (1,7] are used by TopLevelLiveRange.
typedef BitField<int32_t, 7, 6> AssignedRegisterField; typedef BitField<int32_t, 7, 6> AssignedRegisterField;
typedef BitField<MachineRepresentation, 13, 8> RepresentationField; typedef BitField<MachineRepresentation, 13, 8> RepresentationField;
typedef BitField<bool, 21, 1> RecombineField; typedef BitField<bool, 21, 1> RecombineField;
typedef BitField<uint8_t, 22, 6> ControlFlowRegisterHint; typedef BitField<uint8_t, 22, 6> ControlFlowRegisterHint;
// Bit 28 is used by TopLevelLiveRange.
// Unique among children and splinters of the same virtual register. // Unique among children and splinters of the same virtual register.
int relative_id_; int relative_id_;
...@@ -570,8 +569,6 @@ class V8_EXPORT_PRIVATE TopLevelLiveRange final : public LiveRange { ...@@ -570,8 +569,6 @@ class V8_EXPORT_PRIVATE TopLevelLiveRange final : public LiveRange {
bool IsFixed() const { return vreg_ < 0; } bool IsFixed() const { return vreg_ < 0; }
bool IsDeferredFixed() const { return DeferredFixedField::decode(bits_); }
void set_deferred_fixed() { bits_ = DeferredFixedField::update(bits_, true); }
bool is_phi() const { return IsPhiField::decode(bits_); } bool is_phi() const { return IsPhiField::decode(bits_); }
void set_is_phi(bool value) { bits_ = IsPhiField::update(bits_, value); } void set_is_phi(bool value) { bits_ = IsPhiField::update(bits_, value); }
...@@ -781,7 +778,6 @@ class V8_EXPORT_PRIVATE TopLevelLiveRange final : public LiveRange { ...@@ -781,7 +778,6 @@ class V8_EXPORT_PRIVATE TopLevelLiveRange final : public LiveRange {
typedef BitField<bool, 3, 1> IsPhiField; typedef BitField<bool, 3, 1> IsPhiField;
typedef BitField<bool, 4, 1> IsNonLoopPhiField; typedef BitField<bool, 4, 1> IsNonLoopPhiField;
typedef BitField<SpillType, 5, 2> SpillTypeField; typedef BitField<SpillType, 5, 2> SpillTypeField;
typedef BitField<bool, 28, 1> DeferredFixedField;
int vreg_; int vreg_;
int last_child_id_; int last_child_id_;
...@@ -864,8 +860,6 @@ class RegisterAllocationData final : public ZoneObject { ...@@ -864,8 +860,6 @@ class RegisterAllocationData final : public ZoneObject {
// Encodes whether a spill happens in deferred code (kSpillDeferred) or // Encodes whether a spill happens in deferred code (kSpillDeferred) or
// regular code (kSpillAtDefinition). // regular code (kSpillAtDefinition).
enum SpillMode { kSpillAtDefinition, kSpillDeferred }; enum SpillMode { kSpillAtDefinition, kSpillDeferred };
static constexpr int kNumberOfFixedRangesPerRegister = 2;
class PhiMapValue : public ZoneObject { class PhiMapValue : public ZoneObject {
public: public:
PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone); PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone);
...@@ -1067,8 +1061,6 @@ class LiveRangeBuilder final : public ZoneObject { ...@@ -1067,8 +1061,6 @@ class LiveRangeBuilder final : public ZoneObject {
private: private:
using SpillMode = RegisterAllocationData::SpillMode; using SpillMode = RegisterAllocationData::SpillMode;
static constexpr int kNumberOfFixedRangesPerRegister =
RegisterAllocationData::kNumberOfFixedRangesPerRegister;
RegisterAllocationData* data() const { return data_; } RegisterAllocationData* data() const { return data_; }
InstructionSequence* code() const { return data()->code(); } InstructionSequence* code() const { return data()->code(); }
...@@ -1094,9 +1086,8 @@ class LiveRangeBuilder final : public ZoneObject { ...@@ -1094,9 +1086,8 @@ class LiveRangeBuilder final : public ZoneObject {
static int FixedLiveRangeID(int index) { return -index - 1; } static int FixedLiveRangeID(int index) { return -index - 1; }
int FixedFPLiveRangeID(int index, MachineRepresentation rep); int FixedFPLiveRangeID(int index, MachineRepresentation rep);
TopLevelLiveRange* FixedLiveRangeFor(int index, SpillMode spill_mode); TopLevelLiveRange* FixedLiveRangeFor(int index);
TopLevelLiveRange* FixedFPLiveRangeFor(int index, MachineRepresentation rep, TopLevelLiveRange* FixedFPLiveRangeFor(int index, MachineRepresentation rep);
SpillMode spill_mode);
void MapPhiHint(InstructionOperand* operand, UsePosition* use_pos); void MapPhiHint(InstructionOperand* operand, UsePosition* use_pos);
void ResolvePhiHint(InstructionOperand* operand, UsePosition* use_pos); void ResolvePhiHint(InstructionOperand* operand, UsePosition* use_pos);
...@@ -1106,30 +1097,19 @@ class LiveRangeBuilder final : public ZoneObject { ...@@ -1106,30 +1097,19 @@ class LiveRangeBuilder final : public ZoneObject {
UsePosition* NewUsePosition(LifetimePosition pos) { UsePosition* NewUsePosition(LifetimePosition pos) {
return NewUsePosition(pos, nullptr, nullptr, UsePositionHintType::kNone); return NewUsePosition(pos, nullptr, nullptr, UsePositionHintType::kNone);
} }
TopLevelLiveRange* LiveRangeFor(InstructionOperand* operand, TopLevelLiveRange* LiveRangeFor(InstructionOperand* operand);
SpillMode spill_mode);
// Helper methods for building intervals. // Helper methods for building intervals.
UsePosition* Define(LifetimePosition position, InstructionOperand* operand, UsePosition* Define(LifetimePosition position, InstructionOperand* operand,
void* hint, UsePositionHintType hint_type, void* hint, UsePositionHintType hint_type);
SpillMode spill_mode); void Define(LifetimePosition position, InstructionOperand* operand) {
void Define(LifetimePosition position, InstructionOperand* operand, Define(position, operand, nullptr, UsePositionHintType::kNone);
SpillMode spill_mode) {
Define(position, operand, nullptr, UsePositionHintType::kNone, spill_mode);
} }
UsePosition* Use(LifetimePosition block_start, LifetimePosition position, UsePosition* Use(LifetimePosition block_start, LifetimePosition position,
InstructionOperand* operand, void* hint, InstructionOperand* operand, void* hint,
UsePositionHintType hint_type, SpillMode spill_mode); UsePositionHintType hint_type);
void Use(LifetimePosition block_start, LifetimePosition position, void Use(LifetimePosition block_start, LifetimePosition position,
InstructionOperand* operand, SpillMode spill_mode) { InstructionOperand* operand) {
Use(block_start, position, operand, nullptr, UsePositionHintType::kNone, Use(block_start, position, operand, nullptr, UsePositionHintType::kNone);
spill_mode);
}
SpillMode SpillModeForBlock(const InstructionBlock* block) const {
if (FLAG_turbo_control_flow_aware_allocation) {
return block->IsDeferred() ? SpillMode::kSpillDeferred
: SpillMode::kSpillAtDefinition;
}
return SpillMode::kSpillAtDefinition;
} }
RegisterAllocationData* const data_; RegisterAllocationData* const data_;
ZoneMap<InstructionOperand*, UsePosition*> phi_hints_; ZoneMap<InstructionOperand*, UsePosition*> phi_hints_;
...@@ -1265,10 +1245,8 @@ class LinearScanAllocator final : public RegisterAllocator { ...@@ -1265,10 +1245,8 @@ class LinearScanAllocator final : public RegisterAllocator {
void ReloadLiveRanges(RangeWithRegisterSet& to_be_live, void ReloadLiveRanges(RangeWithRegisterSet& to_be_live,
LifetimePosition position); LifetimePosition position);
void UpdateDeferredFixedRanges(SpillMode spill_mode, InstructionBlock* block);
bool BlockIsDeferredOrImmediatePredecessorIsNotDeferred( bool BlockIsDeferredOrImmediatePredecessorIsNotDeferred(
const InstructionBlock* block); const InstructionBlock* block);
bool HasNonDeferredPredecessor(InstructionBlock* block);
struct LiveRangeOrdering { struct LiveRangeOrdering {
bool operator()(const LiveRange* a, const LiveRange* b) const { bool operator()(const LiveRange* a, const LiveRange* b) const {
......
...@@ -419,9 +419,9 @@ DEFINE_BOOL(print_deopt_stress, false, "print number of possible deopt points") ...@@ -419,9 +419,9 @@ DEFINE_BOOL(print_deopt_stress, false, "print number of possible deopt points")
// Flags for TurboFan. // Flags for TurboFan.
DEFINE_BOOL(turbo_sp_frame_access, false, DEFINE_BOOL(turbo_sp_frame_access, false,
"use stack pointer-relative access to frame wherever possible") "use stack pointer-relative access to frame wherever possible")
DEFINE_BOOL(turbo_preprocess_ranges, false, DEFINE_BOOL(turbo_preprocess_ranges, true,
"run pre-register allocation heuristics") "run pre-register allocation heuristics")
DEFINE_BOOL(turbo_control_flow_aware_allocation, true, DEFINE_BOOL(turbo_control_flow_aware_allocation, false,
"consider control flow while allocating registers") "consider control flow while allocating registers")
DEFINE_NEG_IMPLICATION(turbo_control_flow_aware_allocation, DEFINE_NEG_IMPLICATION(turbo_control_flow_aware_allocation,
turbo_preprocess_ranges) turbo_preprocess_ranges)
......
...@@ -113,11 +113,6 @@ TEST_F(RegisterAllocatorTest, SimpleLoop) { ...@@ -113,11 +113,6 @@ TEST_F(RegisterAllocatorTest, SimpleLoop) {
// while(true) { i++ } // while(true) { i++ }
StartBlock(); StartBlock();
auto i_reg = DefineConstant(); auto i_reg = DefineConstant();
// Add a branch around the loop to ensure the end-block
// is connected.
EndBlock(Branch(Reg(DefineConstant()), 3, 1));
StartBlock();
EndBlock(); EndBlock();
{ {
...@@ -132,9 +127,6 @@ TEST_F(RegisterAllocatorTest, SimpleLoop) { ...@@ -132,9 +127,6 @@ TEST_F(RegisterAllocatorTest, SimpleLoop) {
EndLoop(); EndLoop();
} }
StartBlock();
EndBlock();
Allocate(); Allocate();
} }
...@@ -625,10 +617,10 @@ TEST_F(RegisterAllocatorTest, SingleDeferredBlockSpill) { ...@@ -625,10 +617,10 @@ TEST_F(RegisterAllocatorTest, SingleDeferredBlockSpill) {
const int var_def_index = 1; const int var_def_index = 1;
const int call_index = 3; const int call_index = 3;
const bool spill_in_deferred = int expect_no_moves =
FLAG_turbo_preprocess_ranges || FLAG_turbo_control_flow_aware_allocation; FLAG_turbo_preprocess_ranges ? var_def_index : call_index;
int expect_no_moves = spill_in_deferred ? var_def_index : call_index; int expect_spill_move =
int expect_spill_move = spill_in_deferred ? call_index : var_def_index; FLAG_turbo_preprocess_ranges ? call_index : var_def_index;
// We should have no parallel moves at the "expect_no_moves" position. // We should have no parallel moves at the "expect_no_moves" position.
EXPECT_EQ( EXPECT_EQ(
...@@ -693,67 +685,6 @@ TEST_F(RegisterAllocatorTest, MultipleDeferredBlockSpills) { ...@@ -693,67 +685,6 @@ TEST_F(RegisterAllocatorTest, MultipleDeferredBlockSpills) {
GetParallelMoveCount(start_of_b3, Instruction::START, sequence())); GetParallelMoveCount(start_of_b3, Instruction::START, sequence()));
} }
TEST_F(RegisterAllocatorTest, ValidMultipleDeferredBlockSpills) {
if (!FLAG_turbo_control_flow_aware_allocation) return;
StartBlock(); // B0
auto var1 = EmitOI(Reg(0));
auto var2 = EmitOI(Reg(1));
auto var3 = EmitOI(Reg(2));
EndBlock(Branch(Reg(var1, 0), 1, 2));
StartBlock(true); // B1
EmitCall(Slot(-2), Slot(var1));
EndBlock(Jump(5));
StartBlock(); // B2
EmitNop();
EndBlock();
StartBlock(); // B3
EmitNop();
EndBlock(Branch(Reg(var2, 0), 1, 2));
StartBlock(true); // B4
EmitCall(Slot(-1), Slot(var2));
EndBlock(Jump(2));
StartBlock(); // B5
EmitNop();
EndBlock();
StartBlock(); // B6
Return(Reg(var3, 2));
EndBlock();
const int def_of_v2 = 2;
const int call_in_b1 = 4;
const int call_in_b4 = 10;
const int end_of_b1 = 5;
const int end_of_b4 = 11;
const int start_of_b6 = 14;
Allocate();
const int var3_reg = 2;
const int var3_slot = 2;
EXPECT_FALSE(IsParallelMovePresent(def_of_v2, Instruction::START, sequence(),
Reg(var3_reg), Slot()));
EXPECT_TRUE(IsParallelMovePresent(call_in_b1, Instruction::START, sequence(),
Reg(var3_reg), Slot(var3_slot)));
EXPECT_TRUE(IsParallelMovePresent(end_of_b1, Instruction::START, sequence(),
Slot(var3_slot), Reg()));
EXPECT_TRUE(IsParallelMovePresent(call_in_b4, Instruction::START, sequence(),
Reg(var3_reg), Slot(var3_slot)));
EXPECT_TRUE(IsParallelMovePresent(end_of_b4, Instruction::START, sequence(),
Slot(var3_slot), Reg()));
EXPECT_EQ(0,
GetParallelMoveCount(start_of_b6, Instruction::START, sequence()));
}
namespace { namespace {
enum class ParameterType { kFixedSlot, kSlot, kRegister, kFixedRegister }; enum class ParameterType { kFixedSlot, kSlot, kRegister, kFixedRegister };
......
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