Revert "Inlining setters that return one of their arguments."

Bug: 13817614

This reverts commit 8e40c3e662d852da87b6bcfe79355f96ab9e91c7.

Change-Id: Ia7ed2d933514781150b2e0b9855244e383c60187
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index 2d738c5..80a88b8 100644
--- a/compiler/dex/quick/dex_file_method_inliner.cc
+++ b/compiler/dex/quick/dex_file_method_inliner.cc
@@ -412,8 +412,7 @@
       result = GenInlineIGet(mir_graph, bb, invoke, move_result, method, method_idx);
       break;
     case kInlineOpIPut:
-      move_result = mir_graph->FindMoveResult(bb, invoke);
-      result = GenInlineIPut(mir_graph, bb, invoke, move_result, method, method_idx);
+      result = GenInlineIPut(mir_graph, bb, invoke, method, method_idx);
       break;
     default:
       LOG(FATAL) << "Unexpected inline op: " << method.opcode;
@@ -673,8 +672,7 @@
 }
 
 bool DexFileMethodInliner::GenInlineIPut(MIRGraph* mir_graph, BasicBlock* bb, MIR* invoke,
-                                         MIR* move_result, const InlineMethod& method,
-                                         uint32_t method_idx) {
+                                         const InlineMethod& method, uint32_t method_idx) {
   CompilationUnit* cu = mir_graph->GetCurrentDexCompilationUnit()->GetCompilationUnit();
   if (cu->enable_debug & (1 << kDebugSlowFieldPath)) {
     return false;
@@ -685,21 +683,12 @@
   DCHECK_EQ(InlineMethodAnalyser::IPutVariant(opcode), data.op_variant);
   uint32_t object_reg = GetInvokeReg(invoke, data.object_arg);
   uint32_t src_reg = GetInvokeReg(invoke, data.src_arg);
-  uint32_t return_reg =
-      data.return_arg_plus1 != 0u ? GetInvokeReg(invoke, data.return_arg_plus1 - 1u) : 0u;
 
   if (opcode == Instruction::IPUT_WIDE && !WideArgIsInConsecutiveDalvikRegs(invoke, data.src_arg)) {
     // The two halfs of the source value are not in consecutive dalvik registers in INVOKE.
     return false;
   }
 
-  DCHECK(move_result == nullptr || data.return_arg_plus1 != 0u);
-  if (move_result != nullptr && move_result->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE &&
-      !WideArgIsInConsecutiveDalvikRegs(invoke, data.return_arg_plus1 - 1u)) {
-    // The two halfs of the return value are not in consecutive dalvik registers in INVOKE.
-    return false;
-  }
-
   DCHECK_EQ(data.method_is_static != 0u,
             invoke->dalvikInsn.opcode == Instruction::INVOKE_STATIC ||
             invoke->dalvikInsn.opcode == Instruction::INVOKE_STATIC_RANGE);
@@ -714,7 +703,7 @@
     invoke->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
   }
 
-  MIR* insn = AllocReplacementMIR(mir_graph, invoke, move_result);
+  MIR* insn = AllocReplacementMIR(mir_graph, invoke, nullptr);
   insn->dalvikInsn.opcode = opcode;
   insn->dalvikInsn.vA = src_reg;
   insn->dalvikInsn.vB = object_reg;
@@ -726,23 +715,6 @@
   DCHECK_EQ(data.is_volatile, mir_graph->GetIFieldLoweringInfo(insn).IsVolatile() ? 1u : 0u);
 
   bb->InsertMIRAfter(invoke, insn);
-
-  if (move_result != nullptr) {
-    MIR* move = AllocReplacementMIR(mir_graph, invoke, move_result);
-    insn->width = invoke->width;
-    move->offset = move_result->offset;
-    move->width = move_result->width;
-    if (move_result->dalvikInsn.opcode == Instruction::MOVE_RESULT) {
-      move->dalvikInsn.opcode = Instruction::MOVE_FROM16;
-    } else if (move_result->dalvikInsn.opcode == Instruction::MOVE_RESULT_OBJECT) {
-      move->dalvikInsn.opcode = Instruction::MOVE_OBJECT_FROM16;
-    } else {
-      DCHECK_EQ(move_result->dalvikInsn.opcode, Instruction::MOVE_RESULT_WIDE);
-      move->dalvikInsn.opcode = Instruction::MOVE_WIDE_FROM16;
-    }
-    move->dalvikInsn.vA = move_result->dalvikInsn.vA;
-    move->dalvikInsn.vB = return_reg;
-  }
   return true;
 }
 
diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h
index c03f89c..b4e190a 100644
--- a/compiler/dex/quick/dex_file_method_inliner.h
+++ b/compiler/dex/quick/dex_file_method_inliner.h
@@ -302,7 +302,7 @@
     static bool GenInlineIGet(MIRGraph* mir_graph, BasicBlock* bb, MIR* invoke,
                               MIR* move_result, const InlineMethod& method, uint32_t method_idx);
     static bool GenInlineIPut(MIRGraph* mir_graph, BasicBlock* bb, MIR* invoke,
-                              MIR* move_result, const InlineMethod& method, uint32_t method_idx);
+                              const InlineMethod& method, uint32_t method_idx);
 
     ReaderWriterMutex lock_;
     /*
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 6fcdf70..73fdc82 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -120,7 +120,7 @@
 bool Mir2Lir::GenSpecialIGet(MIR* mir, const InlineMethod& special) {
   // FastInstance() already checked by DexFileMethodInliner.
   const InlineIGetIPutData& data = special.d.ifield_data;
-  if (data.method_is_static != 0u || data.object_arg != 0u) {
+  if (data.method_is_static || data.object_arg != 0) {
     // The object is not "this" and has to be null-checked.
     return false;
   }
@@ -151,14 +151,10 @@
 bool Mir2Lir::GenSpecialIPut(MIR* mir, const InlineMethod& special) {
   // FastInstance() already checked by DexFileMethodInliner.
   const InlineIGetIPutData& data = special.d.ifield_data;
-  if (data.method_is_static != 0u || data.object_arg != 0u) {
+  if (data.method_is_static || data.object_arg != 0) {
     // The object is not "this" and has to be null-checked.
     return false;
   }
-  if (data.return_arg_plus1 != 0u) {
-    // The setter returns a method argument which we don't support here.
-    return false;
-  }
 
   bool wide = (data.op_variant == InlineMethodAnalyser::IPutVariant(Instruction::IPUT_WIDE));
 
diff --git a/runtime/quick/inline_method_analyser.cc b/runtime/quick/inline_method_analyser.cc
index 0a1b72e..a9072d8 100644
--- a/runtime/quick/inline_method_analyser.cc
+++ b/runtime/quick/inline_method_analyser.cc
@@ -218,24 +218,16 @@
   uint32_t arg_start = code_item->registers_size_ - code_item->ins_size_;
   DCHECK_GE(object_reg, arg_start);
   DCHECK_LT(object_reg, code_item->registers_size_);
-  uint32_t object_arg = object_reg - arg_start;
-
   DCHECK_LT(opcode == Instruction::IGET_WIDE ? dst_reg + 1 : dst_reg, code_item->registers_size_);
   if (dst_reg != return_reg) {
     return false;  // Not returning the value retrieved by IGET?
   }
 
-  if ((verifier->GetAccessFlags() & kAccStatic) != 0u || object_arg != 0u) {
+  if ((verifier->GetAccessFlags() & kAccStatic) != 0 || object_reg != arg_start) {
     // TODO: Support inlining IGET on other register than "this".
     return false;
   }
 
-  // InlineIGetIPutData::object_arg is only 4 bits wide.
-  static constexpr uint16_t kMaxObjectArg = 15u;
-  if (object_arg > kMaxObjectArg) {
-    return false;
-  }
-
   if (result != nullptr) {
     InlineIGetIPutData* data = &result->d.ifield_data;
     if (!ComputeSpecialAccessorInfo(field_idx, false, verifier, data)) {
@@ -244,10 +236,10 @@
     result->opcode = kInlineOpIGet;
     result->flags = kInlineSpecial;
     data->op_variant = IGetVariant(opcode);
-    data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0 ? 1u : 0u;
-    data->object_arg = object_arg;  // Allow IGET on any register, not just "this".
+    data->object_arg = object_reg - arg_start;  // Allow IGET on any register, not just "this".
     data->src_arg = 0;
-    data->return_arg_plus1 = 0u;
+    data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0;
+    data->reserved = 0;
   }
   return true;
 }
@@ -261,45 +253,29 @@
 
   const Instruction* return_instruction = instruction->Next();
   Instruction::Code return_opcode = return_instruction->Opcode();
-  uint32_t arg_start = code_item->registers_size_ - code_item->ins_size_;
-  uint16_t return_arg_plus1 = 0u;
   if (return_opcode != Instruction::RETURN_VOID) {
-    if (return_opcode != Instruction::RETURN &&
-        return_opcode != Instruction::RETURN_OBJECT &&
-        return_opcode != Instruction::RETURN_WIDE) {
-      return false;
-    }
-    // Returning an argument.
-    uint32_t return_reg = return_instruction->VRegA_11x();
-    DCHECK_GE(return_reg, arg_start);
-    DCHECK_LT(return_opcode == Instruction::RETURN_WIDE ? return_reg + 1u : return_reg,
-              code_item->registers_size_);
-    return_arg_plus1 = return_reg - arg_start + 1u;
+    // TODO: Support returning an argument.
+    // This is needed by builder classes and generated accessor setters.
+    //    builder.setX(value): iput value, this, fieldX; return-object this;
+    //    object.access$nnn(value): iput value, this, fieldX; return value;
+    // Use InlineIGetIPutData::reserved to hold the information.
+    return false;
   }
 
   uint32_t src_reg = instruction->VRegA_22c();
   uint32_t object_reg = instruction->VRegB_22c();
   uint32_t field_idx = instruction->VRegC_22c();
+  uint32_t arg_start = code_item->registers_size_ - code_item->ins_size_;
   DCHECK_GE(object_reg, arg_start);
   DCHECK_LT(object_reg, code_item->registers_size_);
   DCHECK_GE(src_reg, arg_start);
   DCHECK_LT(opcode == Instruction::IPUT_WIDE ? src_reg + 1 : src_reg, code_item->registers_size_);
-  uint32_t object_arg = object_reg - arg_start;
-  uint32_t src_arg = src_reg - arg_start;
 
-  if ((verifier->GetAccessFlags() & kAccStatic) != 0 || object_arg != 0) {
+  if ((verifier->GetAccessFlags() & kAccStatic) != 0 || object_reg != arg_start) {
     // TODO: Support inlining IPUT on other register than "this".
     return false;
   }
 
-  // InlineIGetIPutData::object_arg/src_arg/return_arg_plus1 are each only 4 bits wide.
-  static constexpr uint16_t kMaxObjectArg = 15u;
-  static constexpr uint16_t kMaxSrcArg = 15u;
-  static constexpr uint16_t kMaxReturnArgPlus1 = 15u;
-  if (object_arg > kMaxObjectArg || src_arg > kMaxSrcArg || return_arg_plus1 > kMaxReturnArgPlus1) {
-    return false;
-  }
-
   if (result != nullptr) {
     InlineIGetIPutData* data = &result->d.ifield_data;
     if (!ComputeSpecialAccessorInfo(field_idx, true, verifier, data)) {
@@ -308,10 +284,10 @@
     result->opcode = kInlineOpIPut;
     result->flags = kInlineSpecial;
     data->op_variant = IPutVariant(opcode);
-    data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0 ? 1u : 0u;
-    data->object_arg = object_arg;  // Allow IPUT on any register, not just "this".
-    data->src_arg = src_arg;
-    data->return_arg_plus1 = return_arg_plus1;
+    data->object_arg = object_reg - arg_start;  // Allow IPUT on any register, not just "this".
+    data->src_arg = src_reg - arg_start;
+    data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0;
+    data->reserved = 0;
   }
   return true;
 }
diff --git a/runtime/quick/inline_method_analyser.h b/runtime/quick/inline_method_analyser.h
index 277a01e..8e1a408 100644
--- a/runtime/quick/inline_method_analyser.h
+++ b/runtime/quick/inline_method_analyser.h
@@ -98,10 +98,10 @@
   // opcode-Instruction::IPUT for IPUTs. This is because the runtime
   // doesn't know the OpSize enumeration.
   uint16_t op_variant : 3;
-  uint16_t method_is_static : 1;
   uint16_t object_arg : 4;
   uint16_t src_arg : 4;  // iput only
-  uint16_t return_arg_plus1 : 4;  // iput only, method argument to return + 1, 0 = return void.
+  uint16_t method_is_static : 1;
+  uint16_t reserved : 4;
   uint16_t field_idx;
   uint32_t is_volatile : 1;
   uint32_t field_offset : 31;