summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/builder.cc8
-rw-r--r--compiler/optimizing/code_generator_arm.cc103
-rw-r--r--compiler/optimizing/code_generator_x86.cc131
-rw-r--r--compiler/optimizing/nodes.h19
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)