Separate object register and shadow frame entry.

The shadow frame already escaped. LLVM can't do optimization for the
shadow frame entry.

Change-Id: I3a6e4a3066ebcc9a6530e3313061af3a7d18c456
diff --git a/src/compiler_llvm/dalvik_reg.cc b/src/compiler_llvm/dalvik_reg.cc
index 379fcb0..492d33b 100644
--- a/src/compiler_llvm/dalvik_reg.cc
+++ b/src/compiler_llvm/dalvik_reg.cc
@@ -29,6 +29,8 @@
    public:
     DalvikLocalVarReg(MethodCompiler& method_compiler, uint32_t reg_idx);
 
+    virtual void SetValue(JType jty, JTypeSpace space, llvm::Value* value);
+
     virtual ~DalvikLocalVarReg();
 
    private:
@@ -39,6 +41,7 @@
     llvm::Value* reg_32_;
     llvm::Value* reg_64_;
     llvm::Value* reg_obj_;
+    llvm::Value* reg_shadow_frame_;
   };
 
   class DalvikRetValReg : public DalvikReg {
@@ -201,7 +204,7 @@
 DalvikLocalVarReg::DalvikLocalVarReg(MethodCompiler& method_compiler,
                                      uint32_t reg_idx)
 : DalvikReg(method_compiler), reg_idx_(reg_idx),
-  reg_32_(NULL), reg_64_(NULL), reg_obj_(NULL) {
+  reg_32_(NULL), reg_64_(NULL), reg_obj_(NULL), reg_shadow_frame_(NULL) {
 }
 
 
@@ -209,6 +212,17 @@
 }
 
 
+void DalvikLocalVarReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) {
+  DalvikReg::SetValue(jty, space, value);
+
+  if (jty == kObject) {
+    DCHECK_NE(reg_shadow_frame_, static_cast<llvm::Value*>(NULL))
+      << "Didn't allocate shadow frame entry.";
+    irb_.CreateStore(value, reg_shadow_frame_);
+  }
+}
+
+
 llvm::Value* DalvikLocalVarReg::GetRawAddr(JType jty, JTypeSpace space) {
   switch (GetRegCategoryFromJType(jty)) {
   case kRegCat1nr:
@@ -226,6 +240,7 @@
   case kRegObject:
     if (reg_obj_ == NULL) {
       reg_obj_ = method_compiler_->AllocDalvikLocalVarReg(kRegObject, reg_idx_);
+      reg_shadow_frame_ = method_compiler_->AllocShadowFrameEntry(reg_idx_);
     }
     return reg_obj_;
 
diff --git a/src/compiler_llvm/dalvik_reg.h b/src/compiler_llvm/dalvik_reg.h
index e6e5b05..2b17541 100644
--- a/src/compiler_llvm/dalvik_reg.h
+++ b/src/compiler_llvm/dalvik_reg.h
@@ -47,7 +47,7 @@
     return GetValue(GetJTypeFromShorty(shorty), space);
   }
 
-  void SetValue(JType jty, JTypeSpace space, llvm::Value* value);
+  virtual void SetValue(JType jty, JTypeSpace space, llvm::Value* value);
 
   void SetValue(char shorty, JTypeSpace space, llvm::Value* value) {
     return SetValue(GetJTypeFromShorty(shorty), space, value);
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index a326b13..c8976cd 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -3841,18 +3841,9 @@
     break;
 
   case kRegObject:
-    {
-      irb_.SetInsertPoint(basic_block_shadow_frame_alloca_);
-
-      llvm::Value* gep_index[] = {
-        irb_.getInt32(0), // No pointer displacement
-        irb_.getInt32(1), // SIRT
-        irb_.getInt32(reg_idx) // Pointer field
-      };
-
-      reg_addr = irb_.CreateGEP(shadow_frame_, gep_index,
-                                StringPrintf("p%u", reg_idx));
-    }
+    irb_.SetInsertPoint(basic_block_reg_alloca_);
+    reg_addr = irb_.CreateAlloca(irb_.getJObjectTy(), 0,
+                                 StringPrintf("o%u", reg_idx));
     break;
 
   default:
@@ -3867,6 +3858,29 @@
 }
 
 
+llvm::Value* MethodCompiler::AllocShadowFrameEntry(uint32_t reg_idx) {
+  // Save current IR builder insert point
+  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
+
+  irb_.SetInsertPoint(basic_block_shadow_frame_alloca_);
+
+  llvm::Value* gep_index[] = {
+    irb_.getInt32(0), // No pointer displacement
+    irb_.getInt32(1), // SIRT
+    irb_.getInt32(reg_idx) // Pointer field
+  };
+
+  llvm::Value* reg_addr =
+    irb_.CreateGEP(shadow_frame_, gep_index, StringPrintf("p%u", reg_idx));
+
+  // Restore IRBuilder insert point
+  irb_.restoreIP(irb_ip_original);
+
+  DCHECK_NE(reg_addr, static_cast<llvm::Value*>(NULL));
+  return reg_addr;
+}
+
+
 llvm::Value* MethodCompiler::AllocDalvikRetValReg(RegCategory cat) {
   // Save current IR builder insert point
   llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index d5a4374..e1465dc 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -83,6 +83,8 @@
 
   llvm::Value* AllocDalvikLocalVarReg(RegCategory cat, uint32_t reg_idx);
 
+  llvm::Value* AllocShadowFrameEntry(uint32_t reg_idx);
+
   llvm::Value* AllocDalvikRetValReg(RegCategory cat);