diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2015-05-27 17:18:33 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2015-05-28 10:44:36 +0100 |
commit | 76b1e1799a713a19218de26b171b0aef48a59e98 (patch) | |
tree | 897d0d22d246367eb09d8b825b43c384074083f4 /compiler/optimizing/code_generator_arm.cc | |
parent | 382f5c24eb663ca8fa39a94a038349138a00272a (diff) |
Add a HCurrentMethod node.
This enables register allocation for the current method, so
that users of it don't always load it from the stack.
Currently only used by HLoadClass. Will make follow-up
CLs for the other users.
Change-Id: If73324d85643102faba47fabbbd2755eb258c59c
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 7d26a3c9ae..1cca52270e 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -41,6 +41,7 @@ static bool ExpectedPairLayout(Location location) { } static constexpr int kCurrentMethodStackOffset = 0; +static constexpr Register kMethodRegisterArgument = R0; // We unconditionally allocate R5 to ensure we can do long operations // with baseline. @@ -544,7 +545,7 @@ void CodeGeneratorARM::GenerateFrameEntry() { uint32_t push_mask = (core_spill_mask_ & (~(1 << PC))) | 1 << LR; __ PushList(push_mask); __ cfi().AdjustCFAOffset(kArmWordSize * POPCOUNT(push_mask)); - __ cfi().RelOffsetForMany(DWARFReg(R0), 0, push_mask, kArmWordSize); + __ cfi().RelOffsetForMany(DWARFReg(kMethodRegisterArgument), 0, push_mask, kArmWordSize); if (fpu_spill_mask_ != 0) { SRegister start_register = SRegister(LeastSignificantBit(fpu_spill_mask_)); __ vpushs(start_register, POPCOUNT(fpu_spill_mask_)); @@ -554,7 +555,7 @@ void CodeGeneratorARM::GenerateFrameEntry() { int adjust = GetFrameSize() - FrameEntrySpillSize(); __ AddConstant(SP, -adjust); __ cfi().AdjustCFAOffset(adjust); - __ StoreToOffset(kStoreWord, R0, SP, 0); + __ StoreToOffset(kStoreWord, kMethodRegisterArgument, SP, 0); } void CodeGeneratorARM::GenerateFrameExit() { @@ -803,11 +804,11 @@ void CodeGeneratorARM::Move64(Location destination, Location source) { void CodeGeneratorARM::Move(HInstruction* instruction, Location location, HInstruction* move_for) { LocationSummary* locations = instruction->GetLocations(); - if (locations != nullptr && locations->Out().Equals(location)) { + if (instruction->IsCurrentMethod()) { + Move32(location, Location::StackSlot(kCurrentMethodStackOffset)); + } else if (locations != nullptr && locations->Out().Equals(location)) { return; - } - - if (locations != nullptr && locations->Out().IsConstant()) { + } else if (locations != nullptr && locations->Out().IsConstant()) { HConstant* const_to_move = locations->Out().GetConstant(); if (const_to_move->IsIntConstant() || const_to_move->IsNullConstant()) { int32_t value = GetInt32ValueOf(const_to_move); @@ -1286,7 +1287,7 @@ void InstructionCodeGeneratorARM::VisitInvokeStaticOrDirect(HInvokeStaticOrDirec void LocationsBuilderARM::HandleInvoke(HInvoke* invoke) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall); - locations->AddTemp(Location::RegisterLocation(R0)); + locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument)); InvokeDexCallingConventionVisitorARM calling_convention_visitor; for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) { @@ -2802,9 +2803,19 @@ void LocationsBuilderARM::VisitParameterValue(HParameterValue* instruction) { locations->SetOut(location); } -void InstructionCodeGeneratorARM::VisitParameterValue(HParameterValue* instruction) { +void InstructionCodeGeneratorARM::VisitParameterValue( + HParameterValue* instruction ATTRIBUTE_UNUSED) { // Nothing to do, the parameter is already at its location. - UNUSED(instruction); +} + +void LocationsBuilderARM::VisitCurrentMethod(HCurrentMethod* instruction) { + LocationSummary* locations = + new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); + locations->SetOut(Location::RegisterLocation(kMethodRegisterArgument)); +} + +void InstructionCodeGeneratorARM::VisitCurrentMethod(HCurrentMethod* instruction ATTRIBUTE_UNUSED) { + // Nothing to do, the method is already at its location. } void LocationsBuilderARM::VisitNot(HNot* not_) { @@ -3954,21 +3965,25 @@ void LocationsBuilderARM::VisitLoadClass(HLoadClass* cls) { : LocationSummary::kNoCall; LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(cls, call_kind); + locations->SetInAt(0, Location::RequiresRegister()); locations->SetOut(Location::RequiresRegister()); } void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) { - Register out = cls->GetLocations()->Out().AsRegister<Register>(); + LocationSummary* locations = cls->GetLocations(); + Register out = locations->Out().AsRegister<Register>(); + Register current_method = locations->InAt(0).AsRegister<Register>(); if (cls->IsReferrersClass()) { DCHECK(!cls->CanCallRuntime()); DCHECK(!cls->MustGenerateClinitCheck()); - codegen_->LoadCurrentMethod(out); - __ LoadFromOffset(kLoadWord, out, out, mirror::ArtMethod::DeclaringClassOffset().Int32Value()); + __ LoadFromOffset( + kLoadWord, out, current_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value()); } else { DCHECK(cls->CanCallRuntime()); - codegen_->LoadCurrentMethod(out); - __ LoadFromOffset( - kLoadWord, out, out, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value()); + __ LoadFromOffset(kLoadWord, + out, + current_method, + mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value()); __ LoadFromOffset(kLoadWord, out, out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex())); SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM( |