diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-04-28 17:47:12 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-04-29 10:55:30 +0100 |
commit | a7aca370a7d62ca04a1e24423d90e8020d6f1a58 (patch) | |
tree | 65d501b0f9711abddbea1a9d06623baafa4ae2b3 /compiler/optimizing/code_generator.cc | |
parent | 5dee5df89aa2cefef6c886d5b9b642cc6f1c595b (diff) | |
download | art-a7aca370a7d62ca04a1e24423d90e8020d6f1a58.zip art-a7aca370a7d62ca04a1e24423d90e8020d6f1a58.tar.gz art-a7aca370a7d62ca04a1e24423d90e8020d6f1a58.tar.bz2 |
Setup policies for register allocation.
Change-Id: I857e77530fca3e2fb872fc142a916af1b48400dc
Diffstat (limited to 'compiler/optimizing/code_generator.cc')
-rw-r--r-- | compiler/optimizing/code_generator.cc | 100 |
1 files changed, 98 insertions, 2 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index babb1f5..ff316e5 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -55,9 +55,105 @@ void CodeGenerator::CompileBlock(HBasicBlock* block) { } } +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; + } + } + LOG(FATAL) << "Unreachable"; + return -1; +} + + +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; + } + + // 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); + if (loc.IsRegister()) { + // Check that a register is not specified twice in the summary. + DCHECK(!blocked_registers_[loc.GetEncoding()]); + blocked_registers_[loc.GetEncoding()] = true; + } + } + + for (size_t i = 0, e = locations->GetTempCount(); i < e; ++i) { + 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; + } + } + + SetupBlockedRegisters(blocked_registers_); + + // Allocate all unallocated input locations. + for (size_t i = 0, e = locations->GetInputCount(); i < e; ++i) { + Location loc = locations->InAt(i); + HInstruction* input = instruction->InputAt(i); + if (loc.IsUnallocated()) { + if (loc.GetPolicy() == Location::kRequiresRegister) { + loc = Location::RegisterLocation( + AllocateFreeRegister(input->GetType(), blocked_registers_)); + } else { + DCHECK_EQ(loc.GetPolicy(), Location::kAny); + HLoadLocal* load = input->AsLoadLocal(); + if (load != nullptr) { + loc = GetStackLocation(load); + } else { + loc = Location::RegisterLocation( + AllocateFreeRegister(input->GetType(), blocked_registers_)); + } + } + locations->SetInAt(i, loc); + } + } + + // Allocate all unallocated temp locations. + for (size_t i = 0, e = locations->GetTempCount(); i < e; ++i) { + Location loc = locations->GetTemp(i); + if (loc.IsUnallocated()) { + 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 = Location::RegisterLocation(static_cast<ManagedRegister>( + AllocateFreeRegister(Primitive::kPrimInt, blocked_registers_))); + locations->SetTempAt(i, loc); + } + } + + Location result_location = locations->Out(); + if (result_location.IsUnallocated()) { + switch (result_location.GetPolicy()) { + case Location::kAny: + case Location::kRequiresRegister: + result_location = Location::RegisterLocation( + AllocateFreeRegister(instruction->GetType(), blocked_registers_)); + break; + case Location::kSameAsFirstInput: + result_location = locations->InAt(0); + break; + } + locations->SetOut(result_location); + } +} + void CodeGenerator::InitLocations(HInstruction* instruction) { - if (instruction->GetLocations() == nullptr) return; - for (size_t i = 0; i < instruction->InputCount(); i++) { + if (instruction->GetLocations() == nullptr) { + return; + } + AllocateRegistersLocally(instruction); + for (size_t i = 0, e = instruction->InputCount(); i < e; ++i) { Location location = instruction->GetLocations()->InAt(i); if (location.IsValid()) { // Move the input to the desired location. |