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_x86.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_x86.cc')
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 216 |
1 files changed, 166 insertions, 50 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index dc10830..fbb054a 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -35,6 +35,72 @@ namespace x86 { static constexpr int kNumberOfPushedRegistersAtEntry = 1; static constexpr int kCurrentMethodStackOffset = 0; +CodeGeneratorX86::CodeGeneratorX86(HGraph* graph) + : CodeGenerator(graph, kNumberOfRegIds), + location_builder_(graph, this), + instruction_visitor_(graph, this) {} + +static bool* GetBlockedRegisterPairs(bool* blocked_registers) { + return blocked_registers + kNumberOfAllocIds; +} + +ManagedRegister CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, + bool* blocked_registers) const { + switch (type) { + case Primitive::kPrimLong: { + size_t reg = AllocateFreeRegisterInternal( + GetBlockedRegisterPairs(blocked_registers), kNumberOfRegisterPairs); + X86ManagedRegister pair = + X86ManagedRegister::FromRegisterPair(static_cast<RegisterPair>(reg)); + blocked_registers[pair.AsRegisterPairLow()] = true; + blocked_registers[pair.AsRegisterPairHigh()] = true; + return pair; + } + + case Primitive::kPrimByte: + case Primitive::kPrimBoolean: + case Primitive::kPrimChar: + case Primitive::kPrimShort: + case Primitive::kPrimInt: + case Primitive::kPrimNot: { + size_t reg = AllocateFreeRegisterInternal(blocked_registers, kNumberOfCpuRegisters); + return X86ManagedRegister::FromCpuRegister(static_cast<Register>(reg)); + } + + case Primitive::kPrimFloat: + case Primitive::kPrimDouble: + LOG(FATAL) << "Unimplemented register type " << type; + + case Primitive::kPrimVoid: + LOG(FATAL) << "Unreachable type " << type; + } + + return ManagedRegister::NoRegister(); +} + +void CodeGeneratorX86::SetupBlockedRegisters(bool* blocked_registers) const { + bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers); + + // Don't allocate the dalvik style register pair passing. + blocked_register_pairs[ECX_EDX] = true; + + // Stack register is always reserved. + blocked_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; +} + static Location X86CpuLocation(Register reg) { return Location::RegisterLocation(X86ManagedRegister::FromCpuRegister(reg)); } @@ -90,6 +156,33 @@ int32_t CodeGeneratorX86::GetStackSlot(HLocal* local) const { } } + +Location CodeGeneratorX86::GetStackLocation(HLoadLocal* load) const { + switch (load->GetType()) { + case Primitive::kPrimLong: + return Location::DoubleStackSlot(GetStackSlot(load->GetLocal())); + break; + + case Primitive::kPrimInt: + case Primitive::kPrimNot: + return Location::StackSlot(GetStackSlot(load->GetLocal())); + + case Primitive::kPrimFloat: + case Primitive::kPrimDouble: + LOG(FATAL) << "Unimplemented type " << load->GetType(); + + case Primitive::kPrimBoolean: + case Primitive::kPrimByte: + case Primitive::kPrimChar: + case Primitive::kPrimShort: + case Primitive::kPrimVoid: + LOG(FATAL) << "Unexpected type " << load->GetType(); + } + + LOG(FATAL) << "Unreachable"; + return Location(); +} + static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX }; static constexpr size_t kRuntimeParameterCoreRegistersLength = arraysize(kRuntimeParameterCoreRegisters); @@ -311,13 +404,18 @@ void InstructionCodeGeneratorX86::VisitExit(HExit* exit) { void LocationsBuilderX86::VisitIf(HIf* if_instr) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(if_instr); - locations->SetInAt(0, X86CpuLocation(EAX)); + locations->SetInAt(0, Location::Any()); if_instr->SetLocations(locations); } void InstructionCodeGeneratorX86::VisitIf(HIf* if_instr) { // TODO: Generate the input as a condition, instead of materializing in a register. - __ cmpl(if_instr->GetLocations()->InAt(0).AsX86().AsCpuRegister(), Immediate(0)); + Location location = if_instr->GetLocations()->InAt(0); + if (location.IsRegister()) { + __ cmpl(location.AsX86().AsCpuRegister(), Immediate(0)); + } else { + __ cmpl(Address(ESP, location.GetStackIndex()), Immediate(0)); + } __ j(kEqual, codegen_->GetLabelOf(if_instr->IfFalseSuccessor())); if (!codegen_->GoesToNextBlock(if_instr->GetBlock(), if_instr->IfTrueSuccessor())) { __ jmp(codegen_->GetLabelOf(if_instr->IfTrueSuccessor())); @@ -367,16 +465,22 @@ void InstructionCodeGeneratorX86::VisitStoreLocal(HStoreLocal* store) { void LocationsBuilderX86::VisitEqual(HEqual* equal) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(equal); - locations->SetInAt(0, X86CpuLocation(EAX)); - locations->SetInAt(1, X86CpuLocation(ECX)); - locations->SetOut(X86CpuLocation(EAX)); + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::Any()); + locations->SetOut(Location::SameAsFirstInput()); equal->SetLocations(locations); } void InstructionCodeGeneratorX86::VisitEqual(HEqual* equal) { - __ cmpl(equal->GetLocations()->InAt(0).AsX86().AsCpuRegister(), - equal->GetLocations()->InAt(1).AsX86().AsCpuRegister()); - __ setb(kEqual, equal->GetLocations()->Out().AsX86().AsCpuRegister()); + LocationSummary* locations = equal->GetLocations(); + if (locations->InAt(1).IsRegister()) { + __ cmpl(locations->InAt(0).AsX86().AsCpuRegister(), + locations->InAt(1).AsX86().AsCpuRegister()); + } else { + __ cmpl(locations->InAt(0).AsX86().AsCpuRegister(), + Address(ESP, locations->InAt(1).GetStackIndex())); + } + __ setb(kEqual, locations->Out().AsX86().AsCpuRegister()); } void LocationsBuilderX86::VisitIntConstant(HIntConstant* constant) { @@ -453,7 +557,7 @@ void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) { void LocationsBuilderX86::VisitInvokeStatic(HInvokeStatic* invoke) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(invoke); - locations->AddTemp(X86CpuLocation(EAX)); + locations->AddTemp(Location::RequiresRegister()); InvokeDexCallingConventionVisitor calling_convention_visitor; for (size_t i = 0; i < invoke->InputCount(); i++) { @@ -514,18 +618,11 @@ void InstructionCodeGeneratorX86::VisitInvokeStatic(HInvokeStatic* invoke) { void LocationsBuilderX86::VisitAdd(HAdd* add) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(add); switch (add->GetResultType()) { - case Primitive::kPrimInt: { - locations->SetInAt(0, X86CpuLocation(EAX)); - locations->SetInAt(1, X86CpuLocation(ECX)); - locations->SetOut(X86CpuLocation(EAX)); - break; - } + case Primitive::kPrimInt: case Primitive::kPrimLong: { - locations->SetInAt( - 0, Location::RegisterLocation(X86ManagedRegister::FromRegisterPair(EAX_EDX))); - locations->SetInAt( - 1, Location::RegisterLocation(X86ManagedRegister::FromRegisterPair(ECX_EBX))); - locations->SetOut(Location::RegisterLocation(X86ManagedRegister::FromRegisterPair(EAX_EDX))); + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::Any()); + locations->SetOut(Location::SameAsFirstInput()); break; } @@ -548,18 +645,30 @@ void InstructionCodeGeneratorX86::VisitAdd(HAdd* add) { case Primitive::kPrimInt: { DCHECK_EQ(locations->InAt(0).AsX86().AsCpuRegister(), locations->Out().AsX86().AsCpuRegister()); - __ addl(locations->InAt(0).AsX86().AsCpuRegister(), - locations->InAt(1).AsX86().AsCpuRegister()); + if (locations->InAt(1).IsRegister()) { + __ addl(locations->InAt(0).AsX86().AsCpuRegister(), + locations->InAt(1).AsX86().AsCpuRegister()); + } else { + __ addl(locations->InAt(0).AsX86().AsCpuRegister(), + Address(ESP, locations->InAt(1).GetStackIndex())); + } break; } case Primitive::kPrimLong: { DCHECK_EQ(locations->InAt(0).AsX86().AsRegisterPair(), locations->Out().AsX86().AsRegisterPair()); - __ addl(locations->InAt(0).AsX86().AsRegisterPairLow(), - locations->InAt(1).AsX86().AsRegisterPairLow()); - __ adcl(locations->InAt(0).AsX86().AsRegisterPairHigh(), - locations->InAt(1).AsX86().AsRegisterPairHigh()); + if (locations->InAt(1).IsRegister()) { + __ addl(locations->InAt(0).AsX86().AsRegisterPairLow(), + locations->InAt(1).AsX86().AsRegisterPairLow()); + __ adcl(locations->InAt(0).AsX86().AsRegisterPairHigh(), + locations->InAt(1).AsX86().AsRegisterPairHigh()); + } else { + __ addl(locations->InAt(0).AsX86().AsRegisterPairLow(), + Address(ESP, locations->InAt(1).GetStackIndex())); + __ adcl(locations->InAt(0).AsX86().AsRegisterPairHigh(), + Address(ESP, locations->InAt(1).GetHighStackIndex(kX86WordSize))); + } break; } @@ -578,19 +687,11 @@ void InstructionCodeGeneratorX86::VisitAdd(HAdd* add) { void LocationsBuilderX86::VisitSub(HSub* sub) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(sub); switch (sub->GetResultType()) { - case Primitive::kPrimInt: { - locations->SetInAt(0, X86CpuLocation(EAX)); - locations->SetInAt(1, X86CpuLocation(ECX)); - locations->SetOut(X86CpuLocation(EAX)); - break; - } - + case Primitive::kPrimInt: case Primitive::kPrimLong: { - locations->SetInAt( - 0, Location::RegisterLocation(X86ManagedRegister::FromRegisterPair(EAX_EDX))); - locations->SetInAt( - 1, Location::RegisterLocation(X86ManagedRegister::FromRegisterPair(ECX_EBX))); - locations->SetOut(Location::RegisterLocation(X86ManagedRegister::FromRegisterPair(EAX_EDX))); + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::Any()); + locations->SetOut(Location::SameAsFirstInput()); break; } @@ -613,18 +714,30 @@ void InstructionCodeGeneratorX86::VisitSub(HSub* sub) { case Primitive::kPrimInt: { DCHECK_EQ(locations->InAt(0).AsX86().AsCpuRegister(), locations->Out().AsX86().AsCpuRegister()); - __ subl(locations->InAt(0).AsX86().AsCpuRegister(), - locations->InAt(1).AsX86().AsCpuRegister()); + if (locations->InAt(1).IsRegister()) { + __ subl(locations->InAt(0).AsX86().AsCpuRegister(), + locations->InAt(1).AsX86().AsCpuRegister()); + } else { + __ subl(locations->InAt(0).AsX86().AsCpuRegister(), + Address(ESP, locations->InAt(1).GetStackIndex())); + } break; } case Primitive::kPrimLong: { DCHECK_EQ(locations->InAt(0).AsX86().AsRegisterPair(), locations->Out().AsX86().AsRegisterPair()); - __ subl(locations->InAt(0).AsX86().AsRegisterPairLow(), - locations->InAt(1).AsX86().AsRegisterPairLow()); - __ sbbl(locations->InAt(0).AsX86().AsRegisterPairHigh(), - locations->InAt(1).AsX86().AsRegisterPairHigh()); + if (locations->InAt(1).IsRegister()) { + __ subl(locations->InAt(0).AsX86().AsRegisterPairLow(), + locations->InAt(1).AsX86().AsRegisterPairLow()); + __ sbbl(locations->InAt(0).AsX86().AsRegisterPairHigh(), + locations->InAt(1).AsX86().AsRegisterPairHigh()); + } else { + __ subl(locations->InAt(0).AsX86().AsRegisterPairLow(), + Address(ESP, locations->InAt(1).GetStackIndex())); + __ sbbl(locations->InAt(0).AsX86().AsRegisterPairHigh(), + Address(ESP, locations->InAt(1).GetHighStackIndex(kX86WordSize))); + } break; } @@ -643,14 +756,16 @@ void InstructionCodeGeneratorX86::VisitSub(HSub* sub) { void LocationsBuilderX86::VisitNewInstance(HNewInstance* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); locations->SetOut(X86CpuLocation(EAX)); + InvokeRuntimeCallingConvention calling_convention; + locations->AddTemp(X86CpuLocation(calling_convention.GetRegisterAt(0))); + locations->AddTemp(X86CpuLocation(calling_convention.GetRegisterAt(1))); instruction->SetLocations(locations); } void InstructionCodeGeneratorX86::VisitNewInstance(HNewInstance* instruction) { InvokeRuntimeCallingConvention calling_convention; LoadCurrentMethod(calling_convention.GetRegisterAt(1)); - __ movl(calling_convention.GetRegisterAt(0), - Immediate(instruction->GetTypeIndex())); + __ movl(calling_convention.GetRegisterAt(0), Immediate(instruction->GetTypeIndex())); __ fs()->call( Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pAllocObjectWithAccessCheck))); @@ -676,15 +791,16 @@ void InstructionCodeGeneratorX86::VisitParameterValue(HParameterValue* instructi void LocationsBuilderX86::VisitNot(HNot* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); - locations->SetInAt(0, X86CpuLocation(EAX)); - locations->SetOut(X86CpuLocation(EAX)); + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetOut(Location::SameAsFirstInput()); instruction->SetLocations(locations); } void InstructionCodeGeneratorX86::VisitNot(HNot* instruction) { LocationSummary* locations = instruction->GetLocations(); - DCHECK_EQ(locations->InAt(0).AsX86().AsCpuRegister(), locations->Out().AsX86().AsCpuRegister()); - __ xorl(locations->Out().AsX86().AsCpuRegister(), Immediate(1)); + Location out = locations->Out(); + DCHECK_EQ(locations->InAt(0).AsX86().AsCpuRegister(), out.AsX86().AsCpuRegister()); + __ xorl(out.AsX86().AsCpuRegister(), Immediate(1)); } void LocationsBuilderX86::VisitPhi(HPhi* instruction) { |