Commit 85017f04 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

Reland "Reland "[regalloc] Introduce deferred fixed ranges""

This is a reland of 1ca08865

Original change's description:
> Reland "[regalloc] Introduce deferred fixed ranges"
> 
> This is a reland of b1769313
> 
> 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}
> 
> Change-Id: I1a31150256eb5608db985b144aab7ea457169d0d
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1530810
> Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#60364}

Change-Id: If4a956716e7e4de132f706be2c395cdfdc04ec94
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1532328Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60408}
parent 1d28a5d8
...@@ -651,7 +651,11 @@ std::ostream& operator<<(std::ostream& os, ...@@ -651,7 +651,11 @@ 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();
os << ": AO#" << block->ao_number(); if (block->ao_number().IsValid()) {
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)";
......
...@@ -162,6 +162,7 @@ void LiveRangeMerger::MarkRangesSpilledInDeferredBlocks() { ...@@ -162,6 +162,7 @@ void LiveRangeMerger::MarkRangesSpilledInDeferredBlocks() {
} }
} }
if (child == nullptr) { if (child == nullptr) {
DCHECK(!data()->is_turbo_control_flow_aware_allocation());
top->TreatAsSpilledInDeferredBlock(data()->allocation_zone(), top->TreatAsSpilledInDeferredBlock(data()->allocation_zone(),
code->InstructionBlockCount()); code->InstructionBlockCount());
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -401,11 +401,12 @@ class PipelineData { ...@@ -401,11 +401,12 @@ class PipelineData {
} }
void InitializeRegisterAllocationData(const RegisterConfiguration* config, void InitializeRegisterAllocationData(const RegisterConfiguration* config,
CallDescriptor* call_descriptor) { CallDescriptor* call_descriptor,
RegisterAllocationFlags flags) {
DCHECK_NULL(register_allocation_data_); DCHECK_NULL(register_allocation_data_);
register_allocation_data_ = new (register_allocation_zone()) register_allocation_data_ = new (register_allocation_zone())
RegisterAllocationData(config, register_allocation_zone(), frame(), RegisterAllocationData(config, register_allocation_zone(), frame(),
sequence(), debug_name()); sequence(), flags, debug_name());
} }
void InitializeOsrHelper() { void InitializeOsrHelper() {
...@@ -2862,7 +2863,14 @@ void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config, ...@@ -2862,7 +2863,14 @@ void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config,
data_->sequence()->ValidateDeferredBlockExitPaths(); data_->sequence()->ValidateDeferredBlockExitPaths();
#endif #endif
data->InitializeRegisterAllocationData(config, call_descriptor); RegisterAllocationFlags flags;
if (data->info()->is_turbo_control_flow_aware_allocation()) {
flags |= RegisterAllocationFlag::kTurboControlFlowAwareAllocation;
}
if (data->info()->is_turbo_preprocess_ranges()) {
flags |= RegisterAllocationFlag::kTurboPreprocessRanges;
}
data->InitializeRegisterAllocationData(config, call_descriptor, flags);
if (info()->is_osr()) data->osr_helper()->SetupFrame(data->frame()); if (info()->is_osr()) data->osr_helper()->SetupFrame(data->frame());
Run<MeetRegisterConstraintsPhase>(); Run<MeetRegisterConstraintsPhase>();
...@@ -2883,7 +2891,7 @@ void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config, ...@@ -2883,7 +2891,7 @@ void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config,
data->register_allocation_data()); data->register_allocation_data());
} }
if (FLAG_turbo_preprocess_ranges) { if (info()->is_turbo_preprocess_ranges()) {
Run<SplinterLiveRangesPhase>(); Run<SplinterLiveRangesPhase>();
if (info()->trace_turbo_json_enabled() && if (info()->trace_turbo_json_enabled() &&
!data->MayHaveUnverifiableGraph()) { !data->MayHaveUnverifiableGraph()) {
...@@ -2899,7 +2907,7 @@ void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config, ...@@ -2899,7 +2907,7 @@ void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config,
Run<AllocateFPRegistersPhase<LinearScanAllocator>>(); Run<AllocateFPRegistersPhase<LinearScanAllocator>>();
} }
if (FLAG_turbo_preprocess_ranges) { if (info()->is_turbo_preprocess_ranges()) {
Run<MergeSplintersPhase>(); Run<MergeSplintersPhase>();
} }
......
...@@ -86,6 +86,13 @@ void OptimizedCompilationInfo::ConfigureFlags() { ...@@ -86,6 +86,13 @@ void OptimizedCompilationInfo::ConfigureFlags() {
default: default:
break; break;
} }
if (FLAG_turbo_control_flow_aware_allocation) {
MarkAsTurboControlFlowAwareAllocation();
}
if (FLAG_turbo_preprocess_ranges) {
MarkAsTurboPreprocessRanges();
}
} }
OptimizedCompilationInfo::~OptimizedCompilationInfo() { OptimizedCompilationInfo::~OptimizedCompilationInfo() {
......
...@@ -55,7 +55,9 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final { ...@@ -55,7 +55,9 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final {
kTraceTurboJson = 1 << 14, kTraceTurboJson = 1 << 14,
kTraceTurboGraph = 1 << 15, kTraceTurboGraph = 1 << 15,
kTraceTurboScheduled = 1 << 16, kTraceTurboScheduled = 1 << 16,
kWasmRuntimeExceptionSupport = 1 << 17 kWasmRuntimeExceptionSupport = 1 << 17,
kTurboControlFlowAwareAllocation = 1 << 18,
kTurboPreprocessRanges = 1 << 19
}; };
// Construct a compilation info for optimized compilation. // Construct a compilation info for optimized compilation.
...@@ -84,6 +86,18 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final { ...@@ -84,6 +86,18 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final {
// Flags used by optimized compilation. // Flags used by optimized compilation.
void MarkAsTurboControlFlowAwareAllocation() {
SetFlag(kTurboControlFlowAwareAllocation);
}
bool is_turbo_control_flow_aware_allocation() const {
return GetFlag(kTurboControlFlowAwareAllocation);
}
void MarkAsTurboPreprocessRanges() { SetFlag(kTurboPreprocessRanges); }
bool is_turbo_preprocess_ranges() const {
return GetFlag(kTurboPreprocessRanges);
}
void MarkAsFunctionContextSpecializing() { void MarkAsFunctionContextSpecializing() {
SetFlag(kFunctionContextSpecializing); SetFlag(kFunctionContextSpecializing);
} }
......
...@@ -113,6 +113,11 @@ TEST_F(RegisterAllocatorTest, SimpleLoop) { ...@@ -113,6 +113,11 @@ 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();
{ {
...@@ -127,6 +132,9 @@ TEST_F(RegisterAllocatorTest, SimpleLoop) { ...@@ -127,6 +132,9 @@ TEST_F(RegisterAllocatorTest, SimpleLoop) {
EndLoop(); EndLoop();
} }
StartBlock();
EndBlock();
Allocate(); Allocate();
} }
...@@ -617,10 +625,10 @@ TEST_F(RegisterAllocatorTest, SingleDeferredBlockSpill) { ...@@ -617,10 +625,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;
int expect_no_moves = const bool spill_in_deferred =
FLAG_turbo_preprocess_ranges ? var_def_index : call_index; FLAG_turbo_preprocess_ranges || FLAG_turbo_control_flow_aware_allocation;
int expect_spill_move = int expect_no_moves = spill_in_deferred ? var_def_index : call_index;
FLAG_turbo_preprocess_ranges ? call_index : var_def_index; int expect_spill_move = spill_in_deferred ? 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(
...@@ -685,6 +693,67 @@ TEST_F(RegisterAllocatorTest, MultipleDeferredBlockSpills) { ...@@ -685,6 +693,67 @@ 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