Commit 6828e44b authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[TurboProp] Add support for intra-block allocation to fast reg alloc

Adds support for register allocation within a block to the fast
register allocator. Also adds some unittests covering basic
register allocation. No support yet for spill slot allocation,
so functions that spill don't work yet.

BUG=v8:9684

Change-Id: I91d0fc0660d7b65f59235242fd5e3b1a7618d813
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2297467
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69045}
parent de6bc114
...@@ -311,8 +311,8 @@ class UnallocatedOperand final : public InstructionOperand { ...@@ -311,8 +311,8 @@ class UnallocatedOperand final : public InstructionOperand {
// [lifetime]: Only for non-FIXED_SLOT. // [lifetime]: Only for non-FIXED_SLOT.
bool IsUsedAtStart() const { bool IsUsedAtStart() const {
DCHECK(basic_policy() == EXTENDED_POLICY); return basic_policy() == EXTENDED_POLICY &&
return LifetimeField::decode(value_) == USED_AT_START; LifetimeField::decode(value_) == USED_AT_START;
} }
INSTRUCTION_OPERAND_CASTS(UnallocatedOperand, UNALLOCATED) INSTRUCTION_OPERAND_CASTS(UnallocatedOperand, UNALLOCATED)
......
...@@ -21,6 +21,7 @@ class TickCounter; ...@@ -21,6 +21,7 @@ class TickCounter;
namespace compiler { namespace compiler {
class SinglePassRegisterAllocator;
class VirtualRegisterData; class VirtualRegisterData;
// The MidTierRegisterAllocator is a register allocator specifically designed to // The MidTierRegisterAllocator is a register allocator specifically designed to
...@@ -42,6 +43,15 @@ class MidTierRegisterAllocationData final : public RegisterAllocationData { ...@@ -42,6 +43,15 @@ class MidTierRegisterAllocationData final : public RegisterAllocationData {
VirtualRegisterData& VirtualRegisterDataFor(int virtual_register); VirtualRegisterData& VirtualRegisterDataFor(int virtual_register);
MachineRepresentation RepresentationFor(int virtual_register); MachineRepresentation RepresentationFor(int virtual_register);
// Add a gap move between the given operands |from| and |to|.
MoveOperands* AddGapMove(int instr_index, Instruction::GapPosition position,
const InstructionOperand& from,
const InstructionOperand& to);
// Helpers to get a block from an |rpo_number| or |instr_index|.
const InstructionBlock* GetBlock(const RpoNumber rpo_number);
const InstructionBlock* GetBlock(int instr_index);
// List of all instruction indexs that require a reference map. // List of all instruction indexs that require a reference map.
ZoneVector<int>& reference_map_instructions() { ZoneVector<int>& reference_map_instructions() {
return reference_map_instructions_; return reference_map_instructions_;
...@@ -85,13 +95,31 @@ class MidTierRegisterAllocator final { ...@@ -85,13 +95,31 @@ class MidTierRegisterAllocator final {
// is defined. // is defined.
void DefineOutputs(); void DefineOutputs();
// TODO(rmcilroy): Phase 2 - allocate registers to instructions. // Phase 2: Allocate registers to instructions.
void AllocateRegisters();
private: private:
// Define outputs operations. // Define outputs operations.
void InitializeBlockState(const InstructionBlock* block); void InitializeBlockState(const InstructionBlock* block);
void DefineOutputs(const InstructionBlock* block); void DefineOutputs(const InstructionBlock* block);
// Allocate registers operations.
void AllocateRegisters(const InstructionBlock* block);
bool IsFixedRegisterPolicy(const UnallocatedOperand* operand);
void ReserveFixedRegisters(int instr_index);
SinglePassRegisterAllocator& AllocatorFor(MachineRepresentation rep);
SinglePassRegisterAllocator& AllocatorFor(const UnallocatedOperand* operand);
SinglePassRegisterAllocator& AllocatorFor(const ConstantOperand* operand);
SinglePassRegisterAllocator& general_reg_allocator() {
return *general_reg_allocator_;
}
SinglePassRegisterAllocator& double_reg_allocator() {
return *double_reg_allocator_;
}
VirtualRegisterData& VirtualRegisterDataFor(int virtual_register) const { VirtualRegisterData& VirtualRegisterDataFor(int virtual_register) const {
return data()->VirtualRegisterDataFor(virtual_register); return data()->VirtualRegisterDataFor(virtual_register);
} }
...@@ -103,6 +131,8 @@ class MidTierRegisterAllocator final { ...@@ -103,6 +131,8 @@ class MidTierRegisterAllocator final {
Zone* allocation_zone() const { return data()->allocation_zone(); } Zone* allocation_zone() const { return data()->allocation_zone(); }
MidTierRegisterAllocationData* data_; MidTierRegisterAllocationData* data_;
std::unique_ptr<SinglePassRegisterAllocator> general_reg_allocator_;
std::unique_ptr<SinglePassRegisterAllocator> double_reg_allocator_;
DISALLOW_COPY_AND_ASSIGN(MidTierRegisterAllocator); DISALLOW_COPY_AND_ASSIGN(MidTierRegisterAllocator);
}; };
......
...@@ -2287,6 +2287,7 @@ struct MidTierRegisterAllocatorPhase { ...@@ -2287,6 +2287,7 @@ struct MidTierRegisterAllocatorPhase {
MidTierRegisterAllocator allocator( MidTierRegisterAllocator allocator(
data->mid_tier_register_allocator_data()); data->mid_tier_register_allocator_data());
allocator.DefineOutputs(); allocator.DefineOutputs();
allocator.AllocateRegisters();
} }
}; };
...@@ -2299,7 +2300,6 @@ struct OptimizeMovesPhase { ...@@ -2299,7 +2300,6 @@ struct OptimizeMovesPhase {
} }
}; };
struct FrameElisionPhase { struct FrameElisionPhase {
DECL_PIPELINE_PHASE_CONSTANTS(FrameElision) DECL_PIPELINE_PHASE_CONSTANTS(FrameElision)
...@@ -2308,7 +2308,6 @@ struct FrameElisionPhase { ...@@ -2308,7 +2308,6 @@ struct FrameElisionPhase {
} }
}; };
struct JumpThreadingPhase { struct JumpThreadingPhase {
DECL_PIPELINE_PHASE_CONSTANTS(JumpThreading) DECL_PIPELINE_PHASE_CONSTANTS(JumpThreading)
......
...@@ -214,6 +214,7 @@ v8_source_set("unittests_sources") { ...@@ -214,6 +214,7 @@ v8_source_set("unittests_sources") {
"compiler/persistent-unittest.cc", "compiler/persistent-unittest.cc",
"compiler/redundancy-elimination-unittest.cc", "compiler/redundancy-elimination-unittest.cc",
"compiler/regalloc/live-range-unittest.cc", "compiler/regalloc/live-range-unittest.cc",
"compiler/regalloc/mid-tier-register-allocator-unittest.cc",
"compiler/regalloc/move-optimizer-unittest.cc", "compiler/regalloc/move-optimizer-unittest.cc",
"compiler/regalloc/register-allocator-unittest.cc", "compiler/regalloc/register-allocator-unittest.cc",
"compiler/schedule-unittest.cc", "compiler/schedule-unittest.cc",
......
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/assembler-inl.h"
#include "src/compiler/pipeline.h"
#include "test/unittests/compiler/backend/instruction-sequence-unittest.h"
namespace v8 {
namespace internal {
namespace compiler {
namespace {
class FastRegisterAllocatorTest : public InstructionSequenceTest {
public:
void Allocate() {
WireBlocks();
Pipeline::AllocateRegistersForTesting(config(), sequence(), true, true);
}
};
TEST_F(FastRegisterAllocatorTest, CanAllocateThreeRegisters) {
// return p0 + p1;
StartBlock();
auto a_reg = Parameter();
auto b_reg = Parameter();
auto c_reg = EmitOI(Reg(1), Reg(a_reg, 1), Reg(b_reg));
Return(c_reg);
EndBlock(Last());
Allocate();
}
TEST_F(FastRegisterAllocatorTest, CanAllocateFPRegisters) {
StartBlock();
TestOperand inputs[] = {
Reg(FPParameter(kFloat64)), Reg(FPParameter(kFloat64)),
Reg(FPParameter(kFloat32)), Reg(FPParameter(kFloat32)),
Reg(FPParameter(kSimd128)), Reg(FPParameter(kSimd128))};
VReg out1 = EmitOI(FPReg(1, kFloat64), arraysize(inputs), inputs);
Return(out1);
EndBlock(Last());
Allocate();
}
} // namespace
} // namespace compiler
} // namespace internal
} // namespace v8
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