Fix MethodInfo. Remove unused shadow frame entry.

Change-Id: I140b3640e1b1bd7575dd8134e295409937dbfd4b
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 4021f7b..6c1e194 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -274,8 +274,15 @@
 
   // Allocate the shadow frame now!
   shadow_frame_size_ = 0;
+  uint16_t arg_reg_start = code_item_->registers_size_ - code_item_->ins_size_;
   if (method_info_.need_shadow_frame_entry) {
     for (uint32_t i = 0, num_of_regs = code_item_->registers_size_; i < num_of_regs; ++i) {
+      if (i >= arg_reg_start && !method_info_.set_to_another_object[i]) {
+        // If we don't set argument registers to another object, we don't need the shadow frame
+        // entry for it. Because the arguments must have been in the caller's shadow frame.
+        continue;
+      }
+
       if (IsRegCanBeObject(i)) {
         reg_to_shadow_frame_index_[i] = shadow_frame_size_++;
       }
@@ -4209,8 +4216,10 @@
                          (code_item_->registers_size_ - code_item_->ins_size_);
   bool has_invoke = false;
   bool may_have_loop = false;
-  bool modify_this = false;
   bool may_throw_exception = false;
+  bool assume_this_non_null = false;
+  std::vector<bool>& set_to_another_object = method_info_.set_to_another_object;
+  set_to_another_object.resize(code_item_->registers_size_, false);
 
   Instruction const* insn;
   for (uint32_t dex_pc = 0;
@@ -4229,16 +4238,16 @@
     case Instruction::MOVE_WIDE:
     case Instruction::MOVE_WIDE_FROM16:
     case Instruction::MOVE_WIDE_16:
+    case Instruction::MOVE_RESULT:
+    case Instruction::MOVE_RESULT_WIDE:
+      break;
+
     case Instruction::MOVE_OBJECT:
     case Instruction::MOVE_OBJECT_FROM16:
     case Instruction::MOVE_OBJECT_16:
-    case Instruction::MOVE_RESULT:
-    case Instruction::MOVE_RESULT_WIDE:
     case Instruction::MOVE_RESULT_OBJECT:
     case Instruction::MOVE_EXCEPTION:
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
+      set_to_another_object[dec_insn.vA] = true;
       break;
 
     case Instruction::RETURN_VOID:
@@ -4251,13 +4260,13 @@
     case Instruction::CONST_16:
     case Instruction::CONST:
     case Instruction::CONST_HIGH16:
+      set_to_another_object[dec_insn.vA] = true;
+      break;
+
     case Instruction::CONST_WIDE_16:
     case Instruction::CONST_WIDE_32:
     case Instruction::CONST_WIDE:
     case Instruction::CONST_WIDE_HIGH16:
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
       break;
 
     case Instruction::CONST_STRING:
@@ -4266,16 +4275,12 @@
       if (!compiler_->CanAssumeStringIsPresentInDexCache(dex_cache_, dec_insn.vB)) {
         may_throw_exception = true;
       }
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
+      set_to_another_object[dec_insn.vA] = true;
       break;
 
     case Instruction::CONST_CLASS:
       may_throw_exception = true;
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
+      set_to_another_object[dec_insn.vA] = true;
       break;
 
     case Instruction::MONITOR_ENTER:
@@ -4284,14 +4289,15 @@
       may_throw_exception = true;
       break;
 
-    case Instruction::INSTANCE_OF:
     case Instruction::ARRAY_LENGTH:
+      may_throw_exception = true;
+      break;
+
+    case Instruction::INSTANCE_OF:
     case Instruction::NEW_INSTANCE:
     case Instruction::NEW_ARRAY:
       may_throw_exception = true;
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
+      set_to_another_object[dec_insn.vA] = true;
       break;
 
     case Instruction::FILLED_NEW_ARRAY:
@@ -4314,16 +4320,11 @@
 
     case Instruction::PACKED_SWITCH:
     case Instruction::SPARSE_SWITCH:
-      break;
-
     case Instruction::CMPL_FLOAT:
     case Instruction::CMPG_FLOAT:
     case Instruction::CMPL_DOUBLE:
     case Instruction::CMPG_DOUBLE:
     case Instruction::CMP_LONG:
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
       break;
 
     case Instruction::IF_EQ:
@@ -4362,8 +4363,8 @@
     case Instruction::AGET_CHAR:
     case Instruction::AGET_SHORT:
       may_throw_exception = true;
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
+      if (insn->Opcode() == Instruction::AGET_OBJECT) {
+        set_to_another_object[dec_insn.vA] = true;
       }
       break;
 
@@ -4385,8 +4386,8 @@
     case Instruction::IGET_CHAR:
     case Instruction::IGET_SHORT:
       {
-        if (dec_insn.vA == this_reg_idx) {
-          modify_this = true;
+        if (insn->Opcode() == Instruction::IGET_OBJECT) {
+          set_to_another_object[dec_insn.vA] = true;
         }
         uint32_t reg_idx = dec_insn.vB;
         uint32_t field_idx = dec_insn.vC;
@@ -4399,6 +4400,7 @@
         } else if (reg_idx != this_reg_idx) {
           // NullPointerException
           may_throw_exception = true;
+          assume_this_non_null = true;
         }
       }
       break;
@@ -4422,6 +4424,7 @@
         } else if (reg_idx != this_reg_idx) {
           // NullPointerException
           may_throw_exception = true;
+          assume_this_non_null = true;
         }
       }
       break;
@@ -4434,8 +4437,8 @@
     case Instruction::SGET_CHAR:
     case Instruction::SGET_SHORT:
       {
-        if (dec_insn.vA == this_reg_idx) {
-          modify_this = true;
+        if (insn->Opcode() == Instruction::AGET_OBJECT) {
+          set_to_another_object[dec_insn.vA] = true;
         }
         uint32_t field_idx = dec_insn.vB;
 
@@ -4549,9 +4552,6 @@
     case Instruction::SHL_LONG_2ADDR:
     case Instruction::SHR_LONG_2ADDR:
     case Instruction::USHR_LONG_2ADDR:
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
       break;
 
     case Instruction::DIV_INT:
@@ -4563,9 +4563,6 @@
     case Instruction::DIV_LONG_2ADDR:
     case Instruction::REM_LONG_2ADDR:
       may_throw_exception = true;
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
       break;
 
     case Instruction::ADD_FLOAT:
@@ -4588,9 +4585,6 @@
     case Instruction::MUL_DOUBLE_2ADDR:
     case Instruction::DIV_DOUBLE_2ADDR:
     case Instruction::REM_DOUBLE_2ADDR:
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
       break;
 
     case Instruction::ADD_INT_LIT16:
@@ -4608,10 +4602,8 @@
     case Instruction::SHL_INT_LIT8:
     case Instruction::SHR_INT_LIT8:
     case Instruction::USHR_INT_LIT8:
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
       break;
+
     case Instruction::DIV_INT_LIT16:
     case Instruction::DIV_INT_LIT8:
     case Instruction::REM_INT_LIT16:
@@ -4619,9 +4611,6 @@
       if (dec_insn.vC == 0) {
         may_throw_exception = true;
       }
-      if (dec_insn.vA == this_reg_idx) {
-        modify_this = true;
-      }
       break;
 
     case Instruction::THROW_VERIFICATION_ERROR:
@@ -4674,13 +4663,15 @@
   // According to the statistics, there are few methods that modify the "this" pointer. So this is a
   // simple way to avoid data flow analysis. After we have a high-level IR before IRBuilder, we
   // should remove this trick.
-  method_info_.this_will_not_be_null = !modify_this;
+  method_info_.this_will_not_be_null =
+      (oat_compilation_unit_->IsStatic()) ? (true) : (!set_to_another_object[this_reg_idx]);
   method_info_.has_invoke = has_invoke;
   // If this method has loop or invoke instruction, it may suspend. Thus we need a shadow frame entry
   // for GC.
   method_info_.need_shadow_frame_entry = has_invoke || may_have_loop;
   // If this method may throw an exception, we need a shadow frame for stack trace (dexpc).
-  method_info_.need_shadow_frame = method_info_.need_shadow_frame_entry || may_throw_exception;
+  method_info_.need_shadow_frame = method_info_.need_shadow_frame_entry || may_throw_exception ||
+                                   (assume_this_non_null && !method_info_.this_will_not_be_null);
   // If can only throw exception, but can't suspend check (no loop, no invoke),
   // then there is no shadow frame entry. Only Shadow frame is needed.
   method_info_.lazy_push_shadow_frame =
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index c30ba3d..ec27d96 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -439,6 +439,7 @@
     bool need_shadow_frame_entry;
     bool need_shadow_frame;
     bool lazy_push_shadow_frame;
+    std::vector<bool> set_to_another_object;
   };
   MethodInfo method_info_;