Simplify HInvokeStatic code generation.

HPushArgument is not needed for now (but might be when we start
optimizing). Also, calling convention for 64bits backend will
require to know more about the argument than the argument's
index. Therefore currently let HInvokeStatic setup the arguments,
which is possible because arguments of a calls are virtual registers
and not instructions.

Change-Id: I8753ed6083aa083c5180ab53b436dc8de4f1fe31
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 @@
   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 @@
           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 @@
   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 @@
   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 @@
   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 @@
   __ 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 @@
   M(NewInstance)                                           \
   M(Not)                                                   \
   M(ParameterValue)                                        \
-  M(PushArgument)                                          \
   M(Return)                                                \
   M(ReturnVoid)                                            \
   M(StoreLocal)                                            \
@@ -717,24 +716,6 @@
   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)