Reduce shadow frame size.

Change-Id: Ifbd5cb38d0666a1f5db1abe7da36ff86a93f87b5
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index c5606c7..3f3e0ad 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -60,7 +60,11 @@
     access_flags_(oat_compilation_unit->access_flags_),
     module_(cunit->GetModule()),
     context_(cunit->GetLLVMContext()),
-    irb_(*cunit->GetIRBuilder()), func_(NULL), retval_reg_(NULL),
+    irb_(*cunit->GetIRBuilder()),
+    func_(NULL),
+    regs_(code_item_->registers_size_),
+    reg_to_shadow_frame_index_(code_item_->registers_size_, -1),
+    retval_reg_(NULL),
     basic_block_stack_overflow_(NULL),
     basic_block_reg_alloca_(NULL), basic_block_shadow_frame_alloca_(NULL),
     basic_block_reg_arg_init_(NULL),
@@ -165,7 +169,7 @@
 
   // Create register array
   for (uint16_t r = 0; r < code_item_->registers_size_; ++r) {
-    regs_.push_back(DalvikReg::CreateLocalVarReg(*this, r));
+    regs_[r] = DalvikReg::CreateLocalVarReg(*this, r);
   }
 
   retval_reg_.reset(DalvikReg::CreateRetValReg(*this));
@@ -250,10 +254,12 @@
   irb_.SetInsertPoint(basic_block_shadow_frame_alloca_);
 
   // Allocate the shadow frame now!
-  uint32_t sirt_size = code_item_->registers_size_;
-  // TODO: registers_size_ is a bad approximation.  Compute a
-  // tighter approximation at Dex verifier while performing data-flow
-  // analysis.
+  uint32_t sirt_size = 0;
+  for (uint32_t i = 0, num_of_regs = code_item_->registers_size_; i < num_of_regs; ++i) {
+    if (IsRegCanBeObject(i)) {
+      reg_to_shadow_frame_index_[i] = sirt_size++;
+    }
+  }
 
   llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(sirt_size);
   shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
@@ -2141,10 +2147,7 @@
                     GetNextBasicBlock(dex_pc));
 }
 
-
-RegCategory MethodCompiler::GetInferredRegCategory(uint32_t dex_pc,
-                                                   uint16_t reg_idx) {
-
+InferredRegCategoryMap const* MethodCompiler::GetInferredRegCategoryMap() {
   Compiler::MethodReference mref(dex_file_, method_idx_);
 
   InferredRegCategoryMap const* map =
@@ -2152,9 +2155,22 @@
 
   CHECK_NE(map, static_cast<InferredRegCategoryMap*>(NULL));
 
+  return map;
+}
+
+RegCategory MethodCompiler::GetInferredRegCategory(uint32_t dex_pc,
+                                                   uint16_t reg_idx) {
+  InferredRegCategoryMap const* map = GetInferredRegCategoryMap();
+
   return map->GetRegCategory(dex_pc, reg_idx);
 }
 
+bool MethodCompiler::IsRegCanBeObject(uint16_t reg_idx) {
+  InferredRegCategoryMap const* map = GetInferredRegCategoryMap();
+
+  return map->IsRegCanBeObject(reg_idx);
+}
+
 
 llvm::Value* MethodCompiler::EmitConditionResult(llvm::Value* lhs,
                                                  llvm::Value* rhs,
@@ -3839,6 +3855,11 @@
 
 
 llvm::Value* MethodCompiler::AllocShadowFrameEntry(uint32_t reg_idx) {
+  if (reg_to_shadow_frame_index_[reg_idx] == -1) {
+    // This register dosen't need ShadowFrame entry
+    return NULL;
+  }
+
   std::string reg_name;
 
 #if !defined(NDEBUG)
@@ -3853,7 +3874,7 @@
   llvm::Value* gep_index[] = {
     irb_.getInt32(0), // No pointer displacement
     irb_.getInt32(1), // SIRT
-    irb_.getInt32(reg_idx) // Pointer field
+    irb_.getInt32(reg_to_shadow_frame_index_[reg_idx]) // Pointer field
   };
 
   llvm::Value* reg_addr = irb_.CreateGEP(shadow_frame_, gep_index, reg_name);