OSDN Git Service

Factorize code for common LocationSummary of HInvoke.
authorNicolas Geoffray <ngeoffray@google.com>
Wed, 3 Jun 2015 10:23:52 +0000 (11:23 +0100)
committerNicolas Geoffray <ngeoffray@google.com>
Wed, 3 Jun 2015 10:23:52 +0000 (11:23 +0100)
This is one step forward, we could factorize more, but
I wanted to get this out of the way first.

Change-Id: I6ae411a737eebaecb64974f47af507ce0cfbae85

compiler/optimizing/code_generator.cc
compiler/optimizing/code_generator.h
compiler/optimizing/code_generator_arm.cc
compiler/optimizing/code_generator_arm.h
compiler/optimizing/code_generator_arm64.cc
compiler/optimizing/code_generator_arm64.h
compiler/optimizing/code_generator_x86.cc
compiler/optimizing/code_generator_x86.h
compiler/optimizing/code_generator_x86_64.cc
compiler/optimizing/code_generator_x86_64.h

index 0cd63a6..65aea68 100644 (file)
@@ -288,6 +288,20 @@ int32_t CodeGenerator::GetStackSlot(HLocal* local) const {
   }
 }
 
+void CodeGenerator::CreateCommonInvokeLocationSummary(
+    HInvoke* invoke, InvokeDexCallingConventionVisitor* visitor){
+  ArenaAllocator* allocator = invoke->GetBlock()->GetGraph()->GetArena();
+  LocationSummary* locations = new (allocator) LocationSummary(invoke, LocationSummary::kCall);
+  locations->AddTemp(visitor->GetMethodLocation());
+
+  for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
+    HInstruction* input = invoke->InputAt(i);
+    locations->SetInAt(i, visitor->GetNextLocation(input->GetType()));
+  }
+
+  locations->SetOut(visitor->GetReturnLocation(invoke->GetType()));
+}
+
 void CodeGenerator::BlockIfInRegister(Location location, bool is_out) const {
   // The DCHECKS below check that a register is not specified twice in
   // the summary. The out location can overlap with an input, so we need
index 3012098..c6ebf6d 100644 (file)
@@ -115,6 +115,8 @@ class SlowPathCode : public ArenaObject<kArenaAllocSlowPaths> {
 class InvokeDexCallingConventionVisitor {
  public:
   virtual Location GetNextLocation(Primitive::Type type) = 0;
+  virtual Location GetReturnLocation(Primitive::Type type) const = 0;
+  virtual Location GetMethodLocation() const = 0;
 
  protected:
   InvokeDexCallingConventionVisitor() {}
@@ -338,6 +340,9 @@ class CodeGenerator {
 
   virtual ParallelMoveResolver* GetMoveResolver() = 0;
 
+  static void CreateCommonInvokeLocationSummary(
+      HInvoke* invoke, InvokeDexCallingConventionVisitor* visitor);
+
  protected:
   CodeGenerator(HGraph* graph,
                 size_t number_of_core_registers,
index 987a6c4..022948e 100644 (file)
@@ -681,7 +681,7 @@ Location InvokeDexCallingConventionVisitorARM::GetNextLocation(Primitive::Type t
   return Location();
 }
 
-Location InvokeDexCallingConventionVisitorARM::GetReturnLocation(Primitive::Type type) {
+Location InvokeDexCallingConventionVisitorARM::GetReturnLocation(Primitive::Type type) const {
   switch (type) {
     case Primitive::kPrimBoolean:
     case Primitive::kPrimByte:
@@ -710,6 +710,10 @@ Location InvokeDexCallingConventionVisitorARM::GetReturnLocation(Primitive::Type
   UNREACHABLE();
 }
 
+Location InvokeDexCallingConventionVisitorARM::GetMethodLocation() const {
+  return Location::RegisterLocation(kMethodRegisterArgument);
+}
+
 void CodeGeneratorARM::Move32(Location destination, Location source) {
   if (source.Equals(destination)) {
     return;
@@ -1285,17 +1289,8 @@ void InstructionCodeGeneratorARM::VisitInvokeStaticOrDirect(HInvokeStaticOrDirec
 }
 
 void LocationsBuilderARM::HandleInvoke(HInvoke* invoke) {
-  LocationSummary* locations =
-      new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
-  locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
-
   InvokeDexCallingConventionVisitorARM calling_convention_visitor;
-  for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
-    HInstruction* input = invoke->InputAt(i);
-    locations->SetInAt(i, calling_convention_visitor.GetNextLocation(input->GetType()));
-  }
-
-  locations->SetOut(calling_convention_visitor.GetReturnLocation(invoke->GetType()));
+  CodeGenerator::CreateCommonInvokeLocationSummary(invoke, &calling_convention_visitor);
 }
 
 void LocationsBuilderARM::VisitInvokeVirtual(HInvokeVirtual* invoke) {
index d649cbf..d84f2d3 100644 (file)
@@ -86,7 +86,8 @@ class InvokeDexCallingConventionVisitorARM : public InvokeDexCallingConventionVi
   virtual ~InvokeDexCallingConventionVisitorARM() {}
 
   Location GetNextLocation(Primitive::Type type) OVERRIDE;
-  Location GetReturnLocation(Primitive::Type type);
+  Location GetReturnLocation(Primitive::Type type) const OVERRIDE;
+  Location GetMethodLocation() const OVERRIDE;
 
  private:
   InvokeDexCallingConvention calling_convention;
index 40432e4..689a35a 100644 (file)
@@ -482,6 +482,10 @@ Location InvokeDexCallingConventionVisitorARM64::GetNextLocation(Primitive::Type
   return next_location;
 }
 
+Location InvokeDexCallingConventionVisitorARM64::GetMethodLocation() const {
+  return LocationFrom(x0);
+}
+
 CodeGeneratorARM64::CodeGeneratorARM64(HGraph* graph,
                                        const Arm64InstructionSetFeatures& isa_features,
                                        const CompilerOptions& compiler_options)
@@ -2163,20 +2167,8 @@ void InstructionCodeGeneratorARM64::VisitNullConstant(HNullConstant* constant) {
 }
 
 void LocationsBuilderARM64::HandleInvoke(HInvoke* invoke) {
-  LocationSummary* locations =
-      new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
-  locations->AddTemp(LocationFrom(x0));
-
   InvokeDexCallingConventionVisitorARM64 calling_convention_visitor;
-  for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
-    HInstruction* input = invoke->InputAt(i);
-    locations->SetInAt(i, calling_convention_visitor.GetNextLocation(input->GetType()));
-  }
-
-  Primitive::Type return_type = invoke->GetType();
-  if (return_type != Primitive::kPrimVoid) {
-    locations->SetOut(calling_convention_visitor.GetReturnLocation(return_type));
-  }
+  CodeGenerator::CreateCommonInvokeLocationSummary(invoke, &calling_convention_visitor);
 }
 
 void LocationsBuilderARM64::VisitInvokeInterface(HInvokeInterface* invoke) {
index 7a502e0..c62ba95 100644 (file)
@@ -115,7 +115,7 @@ class InvokeDexCallingConvention : public CallingConvention<vixl::Register, vixl
                           kParameterFPRegistersLength,
                           kArm64PointerSize) {}
 
-  Location GetReturnLocation(Primitive::Type return_type) {
+  Location GetReturnLocation(Primitive::Type return_type) const {
     return ARM64ReturnLocation(return_type);
   }
 
@@ -130,9 +130,10 @@ class InvokeDexCallingConventionVisitorARM64 : public InvokeDexCallingConvention
   virtual ~InvokeDexCallingConventionVisitorARM64() {}
 
   Location GetNextLocation(Primitive::Type type) OVERRIDE;
-  Location GetReturnLocation(Primitive::Type return_type) {
+  Location GetReturnLocation(Primitive::Type return_type) const OVERRIDE {
     return calling_convention.GetReturnLocation(return_type);
   }
+  Location GetMethodLocation() const OVERRIDE;
 
  private:
   InvokeDexCallingConvention calling_convention;
index f63a5d2..4c4fbd9 100644 (file)
@@ -556,6 +556,32 @@ Location CodeGeneratorX86::GetStackLocation(HLoadLocal* load) const {
   UNREACHABLE();
 }
 
+Location InvokeDexCallingConventionVisitorX86::GetReturnLocation(Primitive::Type type) const {
+  switch (type) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimChar:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimInt:
+    case Primitive::kPrimNot:
+      return Location::RegisterLocation(EAX);
+
+    case Primitive::kPrimLong:
+      return Location::RegisterPairLocation(EAX, EDX);
+
+    case Primitive::kPrimVoid:
+      return Location::NoLocation();
+
+    case Primitive::kPrimDouble:
+    case Primitive::kPrimFloat:
+      return Location::FpuRegisterLocation(XMM0);
+  }
+}
+
+Location InvokeDexCallingConventionVisitorX86::GetMethodLocation() const {
+  return Location::RegisterLocation(kMethodRegisterArgument);
+}
+
 Location InvokeDexCallingConventionVisitorX86::GetNextLocation(Primitive::Type type) {
   switch (type) {
     case Primitive::kPrimBoolean:
@@ -977,7 +1003,6 @@ void LocationsBuilderX86::VisitStoreLocal(HStoreLocal* store) {
     default:
       LOG(FATAL) << "Unknown local type " << store->InputAt(1)->GetType();
   }
-  store->SetLocations(locations);
 }
 
 void InstructionCodeGeneratorX86::VisitStoreLocal(HStoreLocal* store) {
@@ -1238,40 +1263,8 @@ void LocationsBuilderX86::VisitInvokeVirtual(HInvokeVirtual* invoke) {
 }
 
 void LocationsBuilderX86::HandleInvoke(HInvoke* invoke) {
-  LocationSummary* locations =
-      new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
-  locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
-
   InvokeDexCallingConventionVisitorX86 calling_convention_visitor;
-  for (size_t i = 0; i < invoke->GetNumberOfArguments(); 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:
-    case Primitive::kPrimShort:
-    case Primitive::kPrimInt:
-    case Primitive::kPrimNot:
-      locations->SetOut(Location::RegisterLocation(EAX));
-      break;
-
-    case Primitive::kPrimLong:
-      locations->SetOut(Location::RegisterPairLocation(EAX, EDX));
-      break;
-
-    case Primitive::kPrimVoid:
-      break;
-
-    case Primitive::kPrimDouble:
-    case Primitive::kPrimFloat:
-      locations->SetOut(Location::FpuRegisterLocation(XMM0));
-      break;
-  }
-
-  invoke->SetLocations(locations);
+  CodeGenerator::CreateCommonInvokeLocationSummary(invoke, &calling_convention_visitor);
 }
 
 void InstructionCodeGeneratorX86::VisitInvokeVirtual(HInvokeVirtual* invoke) {
@@ -3922,7 +3915,6 @@ void LocationsBuilderX86::VisitArrayLength(HArrayLength* instruction) {
   LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction);
   locations->SetInAt(0, Location::RequiresRegister());
   locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
-  instruction->SetLocations(locations);
 }
 
 void InstructionCodeGeneratorX86::VisitArrayLength(HArrayLength* instruction) {
index 6988803..61827a4 100644 (file)
@@ -83,6 +83,8 @@ class InvokeDexCallingConventionVisitorX86 : public InvokeDexCallingConventionVi
   virtual ~InvokeDexCallingConventionVisitorX86() {}
 
   Location GetNextLocation(Primitive::Type type) OVERRIDE;
+  Location GetReturnLocation(Primitive::Type type) const OVERRIDE;
+  Location GetMethodLocation() const OVERRIDE;
 
  private:
   InvokeDexCallingConvention calling_convention;
index ca9a154..febe2bc 100644 (file)
@@ -1245,6 +1245,30 @@ void InstructionCodeGeneratorX86_64::VisitReturn(HReturn* ret) {
   codegen_->GenerateFrameExit();
 }
 
+Location InvokeDexCallingConventionVisitorX86_64::GetReturnLocation(Primitive::Type type) const {
+  switch (type) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimChar:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimInt:
+    case Primitive::kPrimNot:
+    case Primitive::kPrimLong:
+      return Location::RegisterLocation(RAX);
+
+    case Primitive::kPrimVoid:
+      return Location::NoLocation();
+
+    case Primitive::kPrimDouble:
+    case Primitive::kPrimFloat:
+      return Location::FpuRegisterLocation(XMM0);
+  }
+}
+
+Location InvokeDexCallingConventionVisitorX86_64::GetMethodLocation() const {
+  return Location::RegisterLocation(kMethodRegisterArgument);
+}
+
 Location InvokeDexCallingConventionVisitorX86_64::GetNextLocation(Primitive::Type type) {
   switch (type) {
     case Primitive::kPrimBoolean:
@@ -1339,35 +1363,8 @@ void InstructionCodeGeneratorX86_64::VisitInvokeStaticOrDirect(HInvokeStaticOrDi
 }
 
 void LocationsBuilderX86_64::HandleInvoke(HInvoke* invoke) {
-  LocationSummary* locations =
-      new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
-  locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
-
   InvokeDexCallingConventionVisitorX86_64 calling_convention_visitor;
-  for (size_t i = 0; i < invoke->GetNumberOfArguments(); 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:
-    case Primitive::kPrimShort:
-    case Primitive::kPrimInt:
-    case Primitive::kPrimNot:
-    case Primitive::kPrimLong:
-      locations->SetOut(Location::RegisterLocation(RAX));
-      break;
-
-    case Primitive::kPrimVoid:
-      break;
-
-    case Primitive::kPrimDouble:
-    case Primitive::kPrimFloat:
-      locations->SetOut(Location::FpuRegisterLocation(XMM0));
-      break;
-  }
+  CodeGenerator::CreateCommonInvokeLocationSummary(invoke, &calling_convention_visitor);
 }
 
 void LocationsBuilderX86_64::VisitInvokeVirtual(HInvokeVirtual* invoke) {
index c74335b..c19e686 100644 (file)
@@ -76,6 +76,8 @@ class InvokeDexCallingConventionVisitorX86_64 : public InvokeDexCallingConventio
   virtual ~InvokeDexCallingConventionVisitorX86_64() {}
 
   Location GetNextLocation(Primitive::Type type) OVERRIDE;
+  Location GetReturnLocation(Primitive::Type type) const OVERRIDE;
+  Location GetMethodLocation() const OVERRIDE;
 
  private:
   InvokeDexCallingConvention calling_convention;