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
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index fe4c3c3..29dbd8b 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -102,14 +102,14 @@
}
}
-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 @@
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<int>()]);
+ blocked_core_registers_[loc.AsRegisterPairLow<int>()] = true;
+ DCHECK(!blocked_core_registers_[loc.AsRegisterPairHigh<int>()]);
+ blocked_core_registers_[loc.AsRegisterPairHigh<int>()] = true;
}
}
@@ -174,12 +191,14 @@
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 @@
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 @@
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 @@
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 74ad8e9..4eba791 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -109,10 +109,10 @@
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 @@
// 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<bool>(number_of_core_registers)),
+ blocked_fpu_registers_(graph->GetArena()->AllocArray<bool>(number_of_fpu_registers)),
+ blocked_register_pairs_(graph->GetArena()->AllocArray<bool>(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<bool>(number_of_registers)),
is_leaf_(true),
stack_map_stream_(graph->GetArena()) {}
~CodeGenerator() {}
@@ -168,12 +178,9 @@
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 @@
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 @@
GrowableArray<PcInfo> pc_infos_;
GrowableArray<SlowPathCode*> 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 0e6b203..2be5c90 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -204,7 +204,7 @@
}
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 @@
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<RegisterPair>(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 @@
|| 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 @@
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<RegisterPair>(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 @@
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 @@
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_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;
-}
-
-size_t CodeGeneratorARM::GetNumberOfRegisters() const {
- return kNumberOfRegIds;
+ 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 c5a8e55..874db0f 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -163,21 +163,11 @@
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 15a1999..73143d6 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -176,7 +176,7 @@
}
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 @@
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<RegisterPair>(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 @@
|| 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 @@
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
Register reg = static_cast<Register>(
- 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<RegisterPair>(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 @@
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 @@
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 2524725..a1a72a2 100644
--- a/compiler/optimizing/code_generator_x86.h
+++ b/compiler/optimizing/code_generator_x86.h
@@ -165,21 +165,11 @@
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 4b61546..21b21f3 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -185,7 +185,7 @@
}
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 @@
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 @@
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 @@
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;
+ 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;
- 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_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 cba3a54..288f3f6 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -173,21 +173,8 @@
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 c9c3d03..8b32262 100644
--- a/compiler/optimizing/register_allocator.cc
+++ b/compiler/optimizing/register_allocator.cc
@@ -37,18 +37,18 @@
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<bool>(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 021fe88..69e6fce 100644
--- a/compiler/utils/x86/managed_register_x86.cc
+++ b/compiler/utils/x86/managed_register_x86.cc
@@ -51,7 +51,11 @@
};
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;
}