From 71175b7f19a4f6cf9cc264feafd820dbafa371fb Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Thu, 9 Oct 2014 22:13:55 +0100 Subject: [PATCH] Cleanup baseline register allocator. - Use three arrays for blocking regsters instead of one and computing offsets in that array.] - Don't pass blocked_registers_ to methods, just use the field. Change-Id: Ib698564c31127c59b5a64c80f4262394b8394dc6 --- compiler/optimizing/code_generator.cc | 55 ++++++++++++------- compiler/optimizing/code_generator.h | 42 ++++++++++----- compiler/optimizing/code_generator_arm.cc | 80 +++++++++++----------------- compiler/optimizing/code_generator_arm.h | 14 +---- compiler/optimizing/code_generator_x86.cc | 56 +++++++------------ compiler/optimizing/code_generator_x86.h | 14 +---- compiler/optimizing/code_generator_x86_64.cc | 39 +++++++------- compiler/optimizing/code_generator_x86_64.h | 17 +----- compiler/optimizing/register_allocator.cc | 8 +-- compiler/utils/x86/managed_register_x86.cc | 6 ++- 10 files changed, 149 insertions(+), 182 deletions(-) diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index fe4c3c3ba..29dbd8b33 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -102,14 +102,14 @@ void CodeGenerator::GenerateSlowPaths() { } } -size_t CodeGenerator::AllocateFreeRegisterInternal( - bool* blocked_registers, size_t number_of_registers) const { - for (size_t regno = 0; regno < number_of_registers; regno++) { - if (!blocked_registers[regno]) { - blocked_registers[regno] = true; - return regno; +size_t CodeGenerator::FindFreeEntry(bool* array, size_t length) { + for (size_t i = 0; i < length; ++i) { + if (!array[i]) { + array[i] = true; + return i; } } + LOG(FATAL) << "Could not find a register in baseline register allocator"; return -1; } @@ -156,17 +156,34 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const { LocationSummary* locations = instruction->GetLocations(); if (locations == nullptr) return; - for (size_t i = 0, e = GetNumberOfRegisters(); i < e; ++i) { - blocked_registers_[i] = false; + for (size_t i = 0, e = GetNumberOfCoreRegisters(); i < e; ++i) { + blocked_core_registers_[i] = false; + } + + for (size_t i = 0, e = GetNumberOfFloatingPointRegisters(); i < e; ++i) { + blocked_fpu_registers_[i] = false; + } + + for (size_t i = 0, e = number_of_register_pairs_; i < e; ++i) { + blocked_register_pairs_[i] = false; } // Mark all fixed input, temp and output registers as used. for (size_t i = 0, e = locations->GetInputCount(); i < e; ++i) { Location loc = locations->InAt(i); + // The DCHECKS below check that a register is not specified twice in + // the summary. if (loc.IsRegister()) { - // Check that a register is not specified twice in the summary. - DCHECK(!blocked_registers_[loc.GetEncoding()]); - blocked_registers_[loc.GetEncoding()] = true; + DCHECK(!blocked_core_registers_[loc.reg()]); + blocked_core_registers_[loc.reg()] = true; + } else if (loc.IsFpuRegister()) { + DCHECK(!blocked_fpu_registers_[loc.reg()]); + blocked_fpu_registers_[loc.reg()] = true; + } else if (loc.IsRegisterPair()) { + DCHECK(!blocked_core_registers_[loc.AsRegisterPairLow()]); + blocked_core_registers_[loc.AsRegisterPairLow()] = true; + DCHECK(!blocked_core_registers_[loc.AsRegisterPairHigh()]); + blocked_core_registers_[loc.AsRegisterPairHigh()] = true; } } @@ -174,12 +191,14 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const { Location loc = locations->GetTemp(i); if (loc.IsRegister()) { // Check that a register is not specified twice in the summary. - DCHECK(!blocked_registers_[loc.GetEncoding()]); - blocked_registers_[loc.GetEncoding()] = true; + DCHECK(!blocked_core_registers_[loc.reg()]); + blocked_core_registers_[loc.reg()] = true; + } else { + DCHECK_EQ(loc.GetPolicy(), Location::kRequiresRegister); } } - SetupBlockedRegisters(blocked_registers_); + SetupBlockedRegisters(); // Allocate all unallocated input locations. for (size_t i = 0, e = locations->GetInputCount(); i < e; ++i) { @@ -188,14 +207,14 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const { if (loc.IsUnallocated()) { if ((loc.GetPolicy() == Location::kRequiresRegister) || (loc.GetPolicy() == Location::kRequiresFpuRegister)) { - loc = AllocateFreeRegister(input->GetType(), blocked_registers_); + loc = AllocateFreeRegister(input->GetType()); } else { DCHECK_EQ(loc.GetPolicy(), Location::kAny); HLoadLocal* load = input->AsLoadLocal(); if (load != nullptr) { loc = GetStackLocation(load); } else { - loc = AllocateFreeRegister(input->GetType(), blocked_registers_); + loc = AllocateFreeRegister(input->GetType()); } } locations->SetInAt(i, loc); @@ -209,7 +228,7 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const { DCHECK_EQ(loc.GetPolicy(), Location::kRequiresRegister); // TODO: Adjust handling of temps. We currently consider temps to use // core registers. They may also use floating point registers at some point. - loc = AllocateFreeRegister(Primitive::kPrimInt, blocked_registers_); + loc = AllocateFreeRegister(Primitive::kPrimInt); locations->SetTempAt(i, loc); } } @@ -219,7 +238,7 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const { case Location::kAny: case Location::kRequiresRegister: case Location::kRequiresFpuRegister: - result_location = AllocateFreeRegister(instruction->GetType(), blocked_registers_); + result_location = AllocateFreeRegister(instruction->GetType()); break; case Location::kSameAsFirstInput: result_location = locations->InAt(0); diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 74ad8e93f..4eba79172 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -109,10 +109,10 @@ class CodeGenerator : public ArenaObject { void SetFrameSize(uint32_t size) { frame_size_ = size; } uint32_t GetCoreSpillMask() const { return core_spill_mask_; } - virtual size_t GetNumberOfCoreRegisters() const = 0; - virtual size_t GetNumberOfFloatingPointRegisters() const = 0; - virtual size_t GetNumberOfRegisters() const = 0; - virtual void SetupBlockedRegisters(bool* blocked_registers) const = 0; + size_t GetNumberOfCoreRegisters() const { return number_of_core_registers_; } + size_t GetNumberOfFloatingPointRegisters() const { return number_of_fpu_registers_; } + virtual void SetupBlockedRegisters() const = 0; + virtual void DumpCoreRegister(std::ostream& stream, int reg) const = 0; virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const = 0; virtual InstructionSet GetInstructionSet() const = 0; @@ -150,16 +150,26 @@ class CodeGenerator : public ArenaObject { // have not been written to. void ClearSpillSlotsFromLoopPhisInStackMap(HSuspendCheck* suspend_check) const; + bool* GetBlockedCoreRegisters() const { return blocked_core_registers_; } + protected: - CodeGenerator(HGraph* graph, size_t number_of_registers) + CodeGenerator(HGraph* graph, + size_t number_of_core_registers, + size_t number_of_fpu_registers, + size_t number_of_register_pairs) : frame_size_(kUninitializedFrameSize), core_spill_mask_(0), first_register_slot_in_slow_path_(0), + blocked_core_registers_(graph->GetArena()->AllocArray(number_of_core_registers)), + blocked_fpu_registers_(graph->GetArena()->AllocArray(number_of_fpu_registers)), + blocked_register_pairs_(graph->GetArena()->AllocArray(number_of_register_pairs)), + number_of_core_registers_(number_of_core_registers), + number_of_fpu_registers_(number_of_fpu_registers), + number_of_register_pairs_(number_of_register_pairs), graph_(graph), block_labels_(graph->GetArena(), 0), pc_infos_(graph->GetArena(), 32), slow_paths_(graph->GetArena(), 8), - blocked_registers_(graph->GetArena()->AllocArray(number_of_registers)), is_leaf_(true), stack_map_stream_(graph->GetArena()) {} ~CodeGenerator() {} @@ -168,12 +178,9 @@ class CodeGenerator : public ArenaObject { void AllocateRegistersLocally(HInstruction* instruction) const; // Backend specific implementation for allocating a register. - virtual Location AllocateFreeRegister(Primitive::Type type, - bool* blocked_registers) const = 0; + virtual Location AllocateFreeRegister(Primitive::Type type) const = 0; - // Raw implementation of allocating a register: loops over blocked_registers to find - // the first available register. - size_t AllocateFreeRegisterInternal(bool* blocked_registers, size_t number_of_registers) const; + static size_t FindFreeEntry(bool* array, size_t length); virtual Location GetStackLocation(HLoadLocal* load) const = 0; @@ -182,6 +189,16 @@ class CodeGenerator : public ArenaObject { uint32_t core_spill_mask_; uint32_t first_register_slot_in_slow_path_; + // Arrays used when doing register allocation to know which + // registers we can allocate. `SetupBlockedRegisters` updates the + // arrays. + bool* const blocked_core_registers_; + bool* const blocked_fpu_registers_; + bool* const blocked_register_pairs_; + size_t number_of_core_registers_; + size_t number_of_fpu_registers_; + size_t number_of_register_pairs_; + private: void InitLocations(HInstruction* instruction); size_t GetStackOffsetOfSavedRegister(size_t index); @@ -193,9 +210,6 @@ class CodeGenerator : public ArenaObject { GrowableArray pc_infos_; GrowableArray slow_paths_; - // Temporary data structure used when doing register allocation. - bool* const blocked_registers_; - bool is_leaf_; StackMapStream stack_map_stream_; diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 0e6b2031b..2be5c90ed 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -204,7 +204,7 @@ void CodeGeneratorARM::RestoreCoreRegister(Location stack_location, uint32_t reg } CodeGeneratorARM::CodeGeneratorARM(HGraph* graph) - : CodeGenerator(graph, kNumberOfRegIds), + : CodeGenerator(graph, kNumberOfCoreRegisters, kNumberOfDRegisters, kNumberOfRegisterPairs), location_builder_(graph, this), instruction_visitor_(graph, this), move_resolver_(graph->GetArena(), this), @@ -214,24 +214,14 @@ size_t CodeGeneratorARM::FrameEntrySpillSize() const { return kNumberOfPushedRegistersAtEntry * kArmWordSize; } -static bool* GetBlockedRegisterPairs(bool* blocked_registers) { - return blocked_registers + kNumberOfAllocIds; -} - -static bool* GetBlockedDRegisters(bool* blocked_registers) { - return blocked_registers + kNumberOfCoreRegisters + kNumberOfSRegisters; -} - -Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type, - bool* blocked_registers) const { +Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type) const { switch (type) { case Primitive::kPrimLong: { - bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers); - size_t reg = AllocateFreeRegisterInternal(blocked_register_pairs, kNumberOfRegisterPairs); + size_t reg = FindFreeEntry(blocked_register_pairs_, kNumberOfRegisterPairs); ArmManagedRegister pair = ArmManagedRegister::FromRegisterPair(static_cast(reg)); - blocked_registers[pair.AsRegisterPairLow()] = true; - blocked_registers[pair.AsRegisterPairHigh()] = true; + blocked_core_registers_[pair.AsRegisterPairLow()] = true; + blocked_core_registers_[pair.AsRegisterPairHigh()] = true; // Block all other register pairs that share a register with `pair`. for (int i = 0; i < kNumberOfRegisterPairs; i++) { ArmManagedRegister current = @@ -240,7 +230,7 @@ Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type, || current.AsRegisterPairLow() == pair.AsRegisterPairHigh() || current.AsRegisterPairHigh() == pair.AsRegisterPairLow() || current.AsRegisterPairHigh() == pair.AsRegisterPairHigh()) { - blocked_register_pairs[i] = true; + blocked_register_pairs_[i] = true; } } return Location::RegisterPairLocation(pair.AsRegisterPairLow(), pair.AsRegisterPairHigh()); @@ -252,14 +242,13 @@ Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type, case Primitive::kPrimShort: case Primitive::kPrimInt: case Primitive::kPrimNot: { - int reg = AllocateFreeRegisterInternal(blocked_registers, kNumberOfCoreRegisters); + int reg = FindFreeEntry(blocked_core_registers_, kNumberOfCoreRegisters); // Block all register pairs that contain `reg`. - bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers); for (int i = 0; i < kNumberOfRegisterPairs; i++) { ArmManagedRegister current = ArmManagedRegister::FromRegisterPair(static_cast(i)); if (current.AsRegisterPairLow() == reg || current.AsRegisterPairHigh() == reg) { - blocked_register_pairs[i] = true; + blocked_register_pairs_[i] = true; } } return Location::RegisterLocation(reg); @@ -267,7 +256,7 @@ Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type, case Primitive::kPrimFloat: case Primitive::kPrimDouble: { - int reg = AllocateFreeRegisterInternal(GetBlockedDRegisters(blocked_registers), kNumberOfDRegisters); + int reg = FindFreeEntry(blocked_fpu_registers_, kNumberOfDRegisters); return Location::FpuRegisterLocation(reg); } @@ -278,48 +267,41 @@ Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type, return Location(); } -void CodeGeneratorARM::SetupBlockedRegisters(bool* blocked_registers) const { - bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers); - bool* blocked_fpu_registers = GetBlockedDRegisters(blocked_registers); - +void CodeGeneratorARM::SetupBlockedRegisters() const { // Don't allocate the dalvik style register pair passing. - blocked_register_pairs[R1_R2] = true; + blocked_register_pairs_[R1_R2] = true; // Stack register, LR and PC are always reserved. - blocked_registers[SP] = true; - blocked_registers[LR] = true; - blocked_registers[PC] = true; + blocked_core_registers_[SP] = true; + blocked_core_registers_[LR] = true; + blocked_core_registers_[PC] = true; // Reserve R4 for suspend check. - blocked_registers[R4] = true; - blocked_register_pairs[R4_R5] = true; + blocked_core_registers_[R4] = true; + blocked_register_pairs_[R4_R5] = true; // Reserve thread register. - blocked_registers[TR] = true; + blocked_core_registers_[TR] = true; // Reserve temp register. - blocked_registers[IP] = true; + blocked_core_registers_[IP] = true; // TODO: We currently don't use Quick's callee saved registers. // We always save and restore R6 and R7 to make sure we can use three // register pairs for long operations. - blocked_registers[R5] = true; - blocked_registers[R8] = true; - blocked_registers[R10] = true; - blocked_registers[R11] = true; - - blocked_fpu_registers[D8] = true; - blocked_fpu_registers[D9] = true; - blocked_fpu_registers[D10] = true; - blocked_fpu_registers[D11] = true; - blocked_fpu_registers[D12] = true; - blocked_fpu_registers[D13] = true; - blocked_fpu_registers[D14] = true; - blocked_fpu_registers[D15] = true; -} - -size_t CodeGeneratorARM::GetNumberOfRegisters() const { - return kNumberOfRegIds; + blocked_core_registers_[R5] = true; + blocked_core_registers_[R8] = true; + blocked_core_registers_[R10] = true; + blocked_core_registers_[R11] = true; + + blocked_fpu_registers_[D8] = true; + blocked_fpu_registers_[D9] = true; + blocked_fpu_registers_[D10] = true; + blocked_fpu_registers_[D11] = true; + blocked_fpu_registers_[D12] = true; + blocked_fpu_registers_[D13] = true; + blocked_fpu_registers_[D14] = true; + blocked_fpu_registers_[D15] = true; } InstructionCodeGeneratorARM::InstructionCodeGeneratorARM(HGraph* graph, CodeGeneratorARM* codegen) diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h index c5a8e55ae..874db0fd5 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -163,21 +163,11 @@ class CodeGeneratorARM : public CodeGenerator { return &assembler_; } - virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE; - virtual Location AllocateFreeRegister( - Primitive::Type type, bool* blocked_registers) const OVERRIDE; - virtual size_t GetNumberOfRegisters() const OVERRIDE; + virtual void SetupBlockedRegisters() const OVERRIDE; + virtual Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE; virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE; - virtual size_t GetNumberOfCoreRegisters() const OVERRIDE { - return kNumberOfCoreRegisters; - } - - virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE { - return kNumberOfDRegisters; - } - virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE; virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE; diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 15a199964..73143d6ac 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -176,7 +176,7 @@ void CodeGeneratorX86::RestoreCoreRegister(Location stack_location, uint32_t reg } CodeGeneratorX86::CodeGeneratorX86(HGraph* graph) - : CodeGenerator(graph, kNumberOfRegIds), + : CodeGenerator(graph, kNumberOfCpuRegisters, kNumberOfXmmRegisters, kNumberOfRegisterPairs), location_builder_(graph, this), instruction_visitor_(graph, this), move_resolver_(graph->GetArena(), this) {} @@ -185,23 +185,14 @@ size_t CodeGeneratorX86::FrameEntrySpillSize() const { return kNumberOfPushedRegistersAtEntry * kX86WordSize; } -static bool* GetBlockedRegisterPairs(bool* blocked_registers) { - return blocked_registers + kNumberOfAllocIds; -} - -static bool* GetBlockedXmmRegisters(bool* blocked_registers) { - return blocked_registers + kNumberOfCpuRegisters; -} - -Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, bool* blocked_registers) const { +Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type) const { switch (type) { case Primitive::kPrimLong: { - bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers); - size_t reg = AllocateFreeRegisterInternal(blocked_register_pairs, kNumberOfRegisterPairs); + size_t reg = FindFreeEntry(blocked_register_pairs_, kNumberOfRegisterPairs); X86ManagedRegister pair = X86ManagedRegister::FromRegisterPair(static_cast(reg)); - blocked_registers[pair.AsRegisterPairLow()] = true; - blocked_registers[pair.AsRegisterPairHigh()] = true; + blocked_core_registers_[pair.AsRegisterPairLow()] = true; + blocked_core_registers_[pair.AsRegisterPairHigh()] = true; // Block all other register pairs that share a register with `pair`. for (int i = 0; i < kNumberOfRegisterPairs; i++) { X86ManagedRegister current = @@ -210,7 +201,7 @@ Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, bool* bloc || current.AsRegisterPairLow() == pair.AsRegisterPairHigh() || current.AsRegisterPairHigh() == pair.AsRegisterPairLow() || current.AsRegisterPairHigh() == pair.AsRegisterPairHigh()) { - blocked_register_pairs[i] = true; + blocked_register_pairs_[i] = true; } } return Location::RegisterPairLocation(pair.AsRegisterPairLow(), pair.AsRegisterPairHigh()); @@ -223,14 +214,13 @@ Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, bool* bloc case Primitive::kPrimInt: case Primitive::kPrimNot: { Register reg = static_cast( - AllocateFreeRegisterInternal(blocked_registers, kNumberOfCpuRegisters)); + FindFreeEntry(blocked_core_registers_, kNumberOfCpuRegisters)); // Block all register pairs that contain `reg`. - bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers); for (int i = 0; i < kNumberOfRegisterPairs; i++) { X86ManagedRegister current = X86ManagedRegister::FromRegisterPair(static_cast(i)); if (current.AsRegisterPairLow() == reg || current.AsRegisterPairHigh() == reg) { - blocked_register_pairs[i] = true; + blocked_register_pairs_[i] = true; } } return Location::RegisterLocation(reg); @@ -238,8 +228,8 @@ Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, bool* bloc case Primitive::kPrimFloat: case Primitive::kPrimDouble: { - return Location::FpuRegisterLocation(AllocateFreeRegisterInternal( - GetBlockedXmmRegisters(blocked_registers), kNumberOfXmmRegisters)); + return Location::FpuRegisterLocation( + FindFreeEntry(blocked_fpu_registers_, kNumberOfXmmRegisters)); } case Primitive::kPrimVoid: @@ -249,27 +239,21 @@ Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, bool* bloc return Location(); } -void CodeGeneratorX86::SetupBlockedRegisters(bool* blocked_registers) const { - bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers); - +void CodeGeneratorX86::SetupBlockedRegisters() const { // Don't allocate the dalvik style register pair passing. - blocked_register_pairs[ECX_EDX] = true; + blocked_register_pairs_[ECX_EDX] = true; // Stack register is always reserved. - blocked_registers[ESP] = true; + blocked_core_registers_[ESP] = true; // TODO: We currently don't use Quick's callee saved registers. - blocked_registers[EBP] = true; - blocked_registers[ESI] = true; - blocked_registers[EDI] = true; - blocked_register_pairs[EAX_EDI] = true; - blocked_register_pairs[EDX_EDI] = true; - blocked_register_pairs[ECX_EDI] = true; - blocked_register_pairs[EBX_EDI] = true; -} - -size_t CodeGeneratorX86::GetNumberOfRegisters() const { - return kNumberOfRegIds; + blocked_core_registers_[EBP] = true; + blocked_core_registers_[ESI] = true; + blocked_core_registers_[EDI] = true; + blocked_register_pairs_[EAX_EDI] = true; + blocked_register_pairs_[EDX_EDI] = true; + blocked_register_pairs_[ECX_EDI] = true; + blocked_register_pairs_[EBX_EDI] = true; } InstructionCodeGeneratorX86::InstructionCodeGeneratorX86(HGraph* graph, CodeGeneratorX86* codegen) diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index 2524725cf..a1a72a2bd 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -165,21 +165,11 @@ class CodeGeneratorX86 : public CodeGenerator { return &assembler_; } - virtual size_t GetNumberOfRegisters() const OVERRIDE; - virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE; - virtual Location AllocateFreeRegister( - Primitive::Type type, bool* blocked_registers) const OVERRIDE; + virtual void SetupBlockedRegisters() const OVERRIDE; + virtual Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE; virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE; - virtual size_t GetNumberOfCoreRegisters() const OVERRIDE { - return kNumberOfCpuRegisters; - } - - virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE { - return kNumberOfXmmRegisters; - } - virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE; virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE; diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 4b61546f2..21b21f39d 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -185,7 +185,7 @@ void CodeGeneratorX86_64::RestoreCoreRegister(Location stack_location, uint32_t } CodeGeneratorX86_64::CodeGeneratorX86_64(HGraph* graph) - : CodeGenerator(graph, kNumberOfRegIds), + : CodeGenerator(graph, kNumberOfCpuRegisters, kNumberOfFloatRegisters, 0), location_builder_(graph, this), instruction_visitor_(graph, this), move_resolver_(graph->GetArena(), this) {} @@ -200,8 +200,7 @@ InstructionCodeGeneratorX86_64::InstructionCodeGeneratorX86_64(HGraph* graph, assembler_(codegen->GetAssembler()), codegen_(codegen) {} -Location CodeGeneratorX86_64::AllocateFreeRegister(Primitive::Type type, - bool* blocked_registers) const { +Location CodeGeneratorX86_64::AllocateFreeRegister(Primitive::Type type) const { switch (type) { case Primitive::kPrimLong: case Primitive::kPrimByte: @@ -210,14 +209,13 @@ Location CodeGeneratorX86_64::AllocateFreeRegister(Primitive::Type type, case Primitive::kPrimShort: case Primitive::kPrimInt: case Primitive::kPrimNot: { - size_t reg = AllocateFreeRegisterInternal(blocked_registers, kNumberOfCpuRegisters); + size_t reg = FindFreeEntry(blocked_core_registers_, kNumberOfCpuRegisters); return Location::RegisterLocation(reg); } case Primitive::kPrimFloat: case Primitive::kPrimDouble: { - size_t reg = AllocateFreeRegisterInternal( - blocked_registers + kNumberOfCpuRegisters, kNumberOfFloatRegisters); + size_t reg = FindFreeEntry(blocked_fpu_registers_, kNumberOfFloatRegisters); return Location::FpuRegisterLocation(reg); } @@ -228,26 +226,25 @@ Location CodeGeneratorX86_64::AllocateFreeRegister(Primitive::Type type, return Location(); } -void CodeGeneratorX86_64::SetupBlockedRegisters(bool* blocked_registers) const { +void CodeGeneratorX86_64::SetupBlockedRegisters() const { // Stack register is always reserved. - blocked_registers[RSP] = true; + blocked_core_registers_[RSP] = true; // Block the register used as TMP. - blocked_registers[TMP] = true; + blocked_core_registers_[TMP] = true; // TODO: We currently don't use Quick's callee saved registers. - blocked_registers[RBX] = true; - blocked_registers[RBP] = true; - blocked_registers[R12] = true; - blocked_registers[R13] = true; - blocked_registers[R14] = true; - blocked_registers[R15] = true; - - bool* blocked_xmm_registers = blocked_registers + kNumberOfCpuRegisters; - blocked_xmm_registers[XMM12] = true; - blocked_xmm_registers[XMM13] = true; - blocked_xmm_registers[XMM14] = true; - blocked_xmm_registers[XMM15] = true; + blocked_core_registers_[RBX] = true; + blocked_core_registers_[RBP] = true; + blocked_core_registers_[R12] = true; + blocked_core_registers_[R13] = true; + blocked_core_registers_[R14] = true; + blocked_core_registers_[R15] = true; + + blocked_fpu_registers_[XMM12] = true; + blocked_fpu_registers_[XMM13] = true; + blocked_fpu_registers_[XMM14] = true; + blocked_fpu_registers_[XMM15] = true; } void CodeGeneratorX86_64::GenerateFrameEntry() { diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h index cba3a54b0..288f3f61f 100644 --- a/compiler/optimizing/code_generator_x86_64.h +++ b/compiler/optimizing/code_generator_x86_64.h @@ -173,21 +173,8 @@ class CodeGeneratorX86_64 : public CodeGenerator { virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE; - virtual size_t GetNumberOfRegisters() const OVERRIDE { - return kNumberOfRegIds; - } - - virtual size_t GetNumberOfCoreRegisters() const OVERRIDE { - return kNumberOfCpuRegisters; - } - - virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE { - return kNumberOfFloatRegisters; - } - - virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE; - virtual Location AllocateFreeRegister( - Primitive::Type type, bool* blocked_registers) const OVERRIDE; + virtual void SetupBlockedRegisters() const OVERRIDE; + virtual Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE; virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE; virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE; diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index c9c3d036b..8b32262ab 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -37,18 +37,18 @@ RegisterAllocator::RegisterAllocator(ArenaAllocator* allocator, handled_(allocator, 0), active_(allocator, 0), inactive_(allocator, 0), - physical_register_intervals_(allocator, codegen->GetNumberOfRegisters()), + physical_register_intervals_(allocator, codegen->GetNumberOfCoreRegisters()), temp_intervals_(allocator, 4), spill_slots_(allocator, kDefaultNumberOfSpillSlots), safepoints_(allocator, 0), processing_core_registers_(false), number_of_registers_(-1), registers_array_(nullptr), - blocked_registers_(allocator->AllocArray(codegen->GetNumberOfRegisters())), + blocked_registers_(codegen->GetBlockedCoreRegisters()), reserved_out_slots_(0), maximum_number_of_live_registers_(0) { - codegen->SetupBlockedRegisters(blocked_registers_); - physical_register_intervals_.SetSize(codegen->GetNumberOfRegisters()); + codegen->SetupBlockedRegisters(); + physical_register_intervals_.SetSize(codegen->GetNumberOfCoreRegisters()); // Always reserve for the current method and the graph's max out registers. // TODO: compute it instead. reserved_out_slots_ = 1 + codegen->GetGraph()->GetMaximumNumberOfOutVRegs(); diff --git a/compiler/utils/x86/managed_register_x86.cc b/compiler/utils/x86/managed_register_x86.cc index 021fe88c2..69e6fce5c 100644 --- a/compiler/utils/x86/managed_register_x86.cc +++ b/compiler/utils/x86/managed_register_x86.cc @@ -51,7 +51,11 @@ static const RegisterPairDescriptor kRegisterPairs[] = { }; std::ostream& operator<<(std::ostream& os, const RegisterPair& reg) { - os << X86ManagedRegister::FromRegisterPair(reg); + if (reg == kNoRegisterPair) { + os << "kNoRegisterPair"; + } else { + os << X86ManagedRegister::FromRegisterPair(reg); + } return os; } -- 2.11.0