diff options
-rw-r--r-- | compiler/optimizing/builder.cc | 8 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 103 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 131 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 19 |
4 files changed, 135 insertions, 126 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 637cf17..1efdd38 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -282,9 +282,7 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, size_t start_index = 0; if (is_instance_call) { HInstruction* arg = LoadLocal(is_range ? register_index : args[0], Primitive::kPrimNot); - HInstruction* push = new (arena_) HPushArgument(arg, 0); - current_block_->AddInstruction(push); - invoke->SetArgumentAt(0, push); + invoke->SetArgumentAt(0, arg); start_index = 1; } @@ -305,9 +303,7 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, return false; } HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type); - HInstruction* push = new (arena_) HPushArgument(arg, i); - current_block_->AddInstruction(push); - invoke->SetArgumentAt(argument_index, push); + invoke->SetArgumentAt(argument_index, arg); if (type == Primitive::kPrimLong) { i++; } diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index fe61333..cdd9696 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -101,6 +101,58 @@ class InvokeDexCallingConvention : public CallingConvention<Register> { DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); }; +class InvokeDexCallingConventionVisitor { + public: + InvokeDexCallingConventionVisitor() : gp_index_(0) {} + + Location GetNextLocation(Primitive::Type type) { + switch (type) { + case Primitive::kPrimBoolean: + case Primitive::kPrimByte: + case Primitive::kPrimChar: + case Primitive::kPrimShort: + case Primitive::kPrimInt: + case Primitive::kPrimNot: { + uint32_t index = gp_index_++; + if (index < calling_convention.GetNumberOfRegisters()) { + return ArmCoreLocation(calling_convention.GetRegisterAt(index)); + } else { + return Location::StackSlot(calling_convention.GetStackOffsetOf(index)); + } + } + + case Primitive::kPrimLong: { + uint32_t index = gp_index_; + gp_index_ += 2; + if (index + 1 < calling_convention.GetNumberOfRegisters()) { + return Location::RegisterLocation(ArmManagedRegister::FromRegisterPair( + calling_convention.GetRegisterPairAt(index))); + } else if (index + 1 == calling_convention.GetNumberOfRegisters()) { + return Location::QuickParameter(index); + } else { + return Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(index)); + } + } + + case Primitive::kPrimDouble: + case Primitive::kPrimFloat: + LOG(FATAL) << "Unimplemented parameter type " << type; + break; + + case Primitive::kPrimVoid: + LOG(FATAL) << "Unexpected parameter type " << type; + break; + } + return Location(); + } + + private: + InvokeDexCallingConvention calling_convention; + uint32_t gp_index_; + + DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor); +}; + void CodeGeneratorARM::Move32(Location destination, Location source) { if (source.Equals(destination)) { return; @@ -417,52 +469,17 @@ void InstructionCodeGeneratorARM::VisitReturn(HReturn* ret) { codegen_->GenerateFrameExit(); } -void LocationsBuilderARM::VisitPushArgument(HPushArgument* argument) { - LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(argument); - InvokeDexCallingConvention calling_convention; - uint32_t argument_index = argument->GetArgumentIndex(); - switch (argument->InputAt(0)->GetType()) { - case Primitive::kPrimBoolean: - case Primitive::kPrimByte: - case Primitive::kPrimChar: - case Primitive::kPrimShort: - case Primitive::kPrimInt: - case Primitive::kPrimNot: { - if (argument_index < calling_convention.GetNumberOfRegisters()) { - locations->SetInAt(0, ArmCoreLocation(calling_convention.GetRegisterAt(argument_index))); - } else { - locations->SetInAt( - 0, Location::StackSlot(calling_convention.GetStackOffsetOf(argument_index))); - } - break; - } - case Primitive::kPrimLong: { - if (argument_index + 1 < calling_convention.GetNumberOfRegisters()) { - Location location = Location::RegisterLocation(ArmManagedRegister::FromRegisterPair( - calling_convention.GetRegisterPairAt(argument_index))); - locations->SetInAt(0, location); - } else if (argument_index + 1 == calling_convention.GetNumberOfRegisters()) { - locations->SetInAt(0, Location::QuickParameter(argument_index)); - } else { - locations->SetInAt( - 0, Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(argument_index))); - } - break; - } - default: - LOG(FATAL) << "Unimplemented argument type " << argument->InputAt(0)->GetType(); - } - argument->SetLocations(locations); -} - -void InstructionCodeGeneratorARM::VisitPushArgument(HPushArgument* argument) { - // Nothing to do. -} - void LocationsBuilderARM::VisitInvokeStatic(HInvokeStatic* invoke) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(invoke); locations->AddTemp(ArmCoreLocation(R0)); - switch (invoke->GetType()) { + + InvokeDexCallingConventionVisitor calling_convention_visitor; + for (int i = 0; i < invoke->InputCount(); i++) { + HInstruction* input = invoke->InputAt(i); + locations->SetInAt(i, calling_convention_visitor.GetNextLocation(input->GetType())); + } + + switch (invoke->GetType()) { case Primitive::kPrimBoolean: case Primitive::kPrimByte: case Primitive::kPrimChar: diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 7507ee7..7b3d31d 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -105,6 +105,72 @@ class InvokeDexCallingConvention : public CallingConvention<Register> { DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); }; +static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX }; +static constexpr size_t kRuntimeParameterCoreRegistersLength = + arraysize(kRuntimeParameterCoreRegisters); + +class InvokeRuntimeCallingConvention : public CallingConvention<Register> { + public: + InvokeRuntimeCallingConvention() + : CallingConvention(kRuntimeParameterCoreRegisters, + kRuntimeParameterCoreRegistersLength) {} + + private: + DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention); +}; + +class InvokeDexCallingConventionVisitor { + public: + InvokeDexCallingConventionVisitor() : gp_index_(0) {} + + Location GetNextLocation(Primitive::Type type) { + switch (type) { + case Primitive::kPrimBoolean: + case Primitive::kPrimByte: + case Primitive::kPrimChar: + case Primitive::kPrimShort: + case Primitive::kPrimInt: + case Primitive::kPrimNot: { + uint32_t index = gp_index_++; + if (index < calling_convention.GetNumberOfRegisters()) { + return X86CpuLocation(calling_convention.GetRegisterAt(index)); + } else { + return Location::StackSlot(calling_convention.GetStackOffsetOf(index)); + } + } + + case Primitive::kPrimLong: { + uint32_t index = gp_index_; + gp_index_ += 2; + if (index + 1 < calling_convention.GetNumberOfRegisters()) { + return Location::RegisterLocation(X86ManagedRegister::FromRegisterPair( + calling_convention.GetRegisterPairAt(index))); + } else if (index + 1 == calling_convention.GetNumberOfRegisters()) { + return Location::QuickParameter(index); + } else { + return Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(index)); + } + } + + case Primitive::kPrimDouble: + case Primitive::kPrimFloat: + LOG(FATAL) << "Unimplemented parameter type " << type; + break; + + case Primitive::kPrimVoid: + LOG(FATAL) << "Unexpected parameter type " << type; + break; + } + return Location(); + } + + private: + InvokeDexCallingConvention calling_convention; + uint32_t gp_index_; + + DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor); +}; + void CodeGeneratorX86::Move32(Location destination, Location source) { if (source.Equals(destination)) { return; @@ -413,67 +479,16 @@ void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) { __ ret(); } -static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX }; -static constexpr size_t kRuntimeParameterCoreRegistersLength = - arraysize(kRuntimeParameterCoreRegisters); - -class InvokeRuntimeCallingConvention : public CallingConvention<Register> { - public: - InvokeRuntimeCallingConvention() - : CallingConvention(kRuntimeParameterCoreRegisters, - kRuntimeParameterCoreRegistersLength) {} - - private: - DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention); -}; - -void LocationsBuilderX86::VisitPushArgument(HPushArgument* argument) { - LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(argument); - InvokeDexCallingConvention calling_convention; - uint32_t argument_index = argument->GetArgumentIndex(); - switch (argument->InputAt(0)->GetType()) { - case Primitive::kPrimBoolean: - case Primitive::kPrimByte: - case Primitive::kPrimChar: - case Primitive::kPrimShort: - case Primitive::kPrimInt: - case Primitive::kPrimNot: { - if (argument_index < calling_convention.GetNumberOfRegisters()) { - locations->SetInAt( - 0, X86CpuLocation(calling_convention.GetRegisterAt(argument->GetArgumentIndex()))); - } else { - locations->SetInAt( - 0, Location::StackSlot(calling_convention.GetStackOffsetOf(argument_index))); - } - break; - } - case Primitive::kPrimLong: { - if (argument_index + 1 < calling_convention.GetNumberOfRegisters()) { - Location location = Location::RegisterLocation(X86ManagedRegister::FromRegisterPair( - calling_convention.GetRegisterPairAt(argument_index))); - locations->SetInAt(0, location); - } else if (argument_index + 1 == calling_convention.GetNumberOfRegisters()) { - locations->SetInAt(0, Location::QuickParameter(argument_index)); - } else { - locations->SetInAt( - 0, Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(argument_index))); - } - break; - } - default: - LOG(FATAL) << "Unimplemented argument type " << argument->InputAt(0)->GetType(); - } - - argument->SetLocations(locations); -} - -void InstructionCodeGeneratorX86::VisitPushArgument(HPushArgument* argument) { - // Nothing to do. -} - void LocationsBuilderX86::VisitInvokeStatic(HInvokeStatic* invoke) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(invoke); locations->AddTemp(X86CpuLocation(EAX)); + + InvokeDexCallingConventionVisitor calling_convention_visitor; + for (int i = 0; i < invoke->InputCount(); i++) { + HInstruction* input = invoke->InputAt(i); + locations->SetInAt(i, calling_convention_visitor.GetNextLocation(input->GetType())); + } + switch (invoke->GetType()) { case Primitive::kPrimBoolean: case Primitive::kPrimByte: diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index d7e74f8..3da9ed9 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -230,7 +230,6 @@ class HBasicBlock : public ArenaObject { M(NewInstance) \ M(Not) \ M(ParameterValue) \ - M(PushArgument) \ M(Return) \ M(ReturnVoid) \ M(StoreLocal) \ @@ -717,24 +716,6 @@ class HNewInstance : public HTemplateInstruction<0> { DISALLOW_COPY_AND_ASSIGN(HNewInstance); }; -// HPushArgument nodes are inserted after the evaluation of an argument -// of a call. Their mere purpose is to ease the code generator's work. -class HPushArgument : public HTemplateInstruction<1> { - public: - HPushArgument(HInstruction* argument, uint8_t argument_index) : argument_index_(argument_index) { - SetRawInputAt(0, argument); - } - - uint8_t GetArgumentIndex() const { return argument_index_; } - - DECLARE_INSTRUCTION(PushArgument) - - private: - const uint8_t argument_index_; - - DISALLOW_COPY_AND_ASSIGN(HPushArgument); -}; - class HAdd : public HBinaryOperation { public: HAdd(Primitive::Type result_type, HInstruction* left, HInstruction* right) |