Refactor dalvik_reg.
Also, fix ComputeMethodInfo, ARRAY_LENGTH may throw exception.
Don't store arguments to shadow frame, it already existed in the
caller's shadow frame.
Change-Id: I184a93ed7f3caea924514d425e6a00dc60464f90
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 2781598..f76f57b 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -19,6 +19,7 @@
#include "backend_types.h"
#include "compilation_unit.h"
#include "compiler.h"
+#include "dalvik_reg.h"
#include "inferred_reg_category_map.h"
#include "ir_builder.h"
#include "logging.h"
@@ -63,6 +64,7 @@
irb_(*cunit->GetIRBuilder()),
func_(NULL),
regs_(code_item_->registers_size_),
+ shadow_frame_entries_(code_item_->registers_size_),
reg_to_shadow_frame_index_(code_item_->registers_size_, -1),
retval_reg_(NULL),
basic_block_stack_overflow_(NULL),
@@ -170,18 +172,29 @@
irb_.SetInsertPoint(basic_block_alloca_);
jvalue_temp_ = irb_.CreateAlloca(irb_.getJValueTy());
- // Create register array
- for (uint16_t r = 0; r < code_item_->registers_size_; ++r) {
- regs_[r] = DalvikReg::CreateLocalVarReg(*this, r);
- }
-
- retval_reg_.reset(DalvikReg::CreateRetValReg(*this));
-
// Create Shadow Frame
if (method_info_.need_shadow_frame) {
EmitPrologueAllocShadowFrame();
}
+ // Create register array
+ for (uint16_t r = 0; r < code_item_->registers_size_; ++r) {
+ std::string name;
+#if !defined(NDEBUG)
+ name = StringPrintf("%u", r);
+#endif
+ regs_[r] = new DalvikReg(*this, name);
+
+ // Cache shadow frame entry address
+ shadow_frame_entries_[r] = GetShadowFrameEntry(r);
+ }
+
+ std::string name;
+#if !defined(NDEBUG)
+ name = "_res";
+#endif
+ retval_reg_.reset(new DalvikReg(*this, name));
+
// Store argument to dalvik register
irb_.SetInsertPoint(basic_block_reg_arg_init_);
EmitPrologueAssignArgRegister();
@@ -324,13 +337,13 @@
++arg_iter; // skip method object
if (!oat_compilation_unit_->IsStatic()) {
- EmitStoreDalvikReg(arg_reg, kObject, kAccurate, arg_iter);
+ regs_[arg_reg]->SetValue(kObject, kAccurate, arg_iter);
++arg_iter;
++arg_reg;
}
for (uint32_t i = 1; i < shorty_size; ++i, ++arg_iter) {
- EmitStoreDalvikReg(arg_reg, shorty[i], kAccurate, arg_iter);
+ regs_[arg_reg]->SetValue(shorty[i], kAccurate, arg_iter);
++arg_reg;
if (shorty[i] == 'J' || shorty[i] == 'D') {
@@ -3876,14 +3889,13 @@
}
-llvm::Value* MethodCompiler::AllocDalvikLocalVarReg(RegCategory cat,
- uint32_t reg_idx) {
+llvm::Value* MethodCompiler::AllocDalvikReg(RegCategory cat, const std::string& name) {
// Get reg_type and reg_name from DalvikReg
llvm::Type* reg_type = DalvikReg::GetRegCategoryEquivSizeTy(irb_, cat);
std::string reg_name;
#if !defined(NDEBUG)
- StringAppendF(®_name, "%c%u", DalvikReg::GetRegCategoryNamePrefix(cat), reg_idx);
+ StringAppendF(®_name, "%c%s", DalvikReg::GetRegCategoryNamePrefix(cat), name.c_str());
#endif
// Save current IR builder insert point
@@ -3901,7 +3913,7 @@
}
-llvm::Value* MethodCompiler::AllocShadowFrameEntry(uint32_t reg_idx) {
+llvm::Value* MethodCompiler::GetShadowFrameEntry(uint32_t reg_idx) {
if (reg_to_shadow_frame_index_[reg_idx] == -1) {
// This register dosen't need ShadowFrame entry
return NULL;
@@ -3914,7 +3926,7 @@
std::string reg_name;
#if !defined(NDEBUG)
- StringAppendF(®_name, "o%u", reg_idx);
+ StringAppendF(®_name, "s%u", reg_idx);
#endif
// Save current IR builder insert point
@@ -3938,30 +3950,6 @@
}
-llvm::Value* MethodCompiler::AllocDalvikRetValReg(RegCategory cat) {
- // Get reg_type and reg_name from DalvikReg
- llvm::Type* reg_type = DalvikReg::GetRegCategoryEquivSizeTy(irb_, cat);
- std::string reg_name;
-
-#if !defined(NDEBUG)
- StringAppendF(®_name, "%c_res", DalvikReg::GetRegCategoryNamePrefix(cat));
-#endif
-
- // Save current IR builder insert point
- llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
- irb_.SetInsertPoint(basic_block_alloca_);
-
- // Alloca
- llvm::Value* reg_addr = irb_.CreateAlloca(reg_type, 0, reg_name);
-
- // Restore IRBuilder insert point
- irb_.restoreIP(irb_ip_original);
-
- DCHECK_NE(reg_addr, static_cast<llvm::Value*>(NULL));
- return reg_addr;
-}
-
-
void MethodCompiler::EmitPopShadowFrame() {
if (!method_info_.need_shadow_frame) {
return;
@@ -3981,6 +3969,48 @@
}
+llvm::Value* MethodCompiler::EmitLoadDalvikReg(uint32_t reg_idx, JType jty,
+ JTypeSpace space) {
+ return regs_[reg_idx]->GetValue(jty, space);
+}
+
+llvm::Value* MethodCompiler::EmitLoadDalvikReg(uint32_t reg_idx, char shorty,
+ JTypeSpace space) {
+ return EmitLoadDalvikReg(reg_idx, GetJTypeFromShorty(shorty), space);
+}
+
+void MethodCompiler::EmitStoreDalvikReg(uint32_t reg_idx, JType jty,
+ JTypeSpace space, llvm::Value* new_value) {
+ regs_[reg_idx]->SetValue(jty, space, new_value);
+ if (jty == kObject && shadow_frame_entries_[reg_idx] != NULL) {
+ irb_.CreateStore(new_value, shadow_frame_entries_[reg_idx], kTBAAShadowFrame);
+ }
+}
+
+void MethodCompiler::EmitStoreDalvikReg(uint32_t reg_idx, char shorty,
+ JTypeSpace space, llvm::Value* new_value) {
+ EmitStoreDalvikReg(reg_idx, GetJTypeFromShorty(shorty), space, new_value);
+}
+
+llvm::Value* MethodCompiler::EmitLoadDalvikRetValReg(JType jty, JTypeSpace space) {
+ return retval_reg_->GetValue(jty, space);
+}
+
+llvm::Value* MethodCompiler::EmitLoadDalvikRetValReg(char shorty, JTypeSpace space) {
+ return EmitLoadDalvikRetValReg(GetJTypeFromShorty(shorty), space);
+}
+
+void MethodCompiler::EmitStoreDalvikRetValReg(JType jty, JTypeSpace space,
+ llvm::Value* new_value) {
+ retval_reg_->SetValue(jty, space, new_value);
+}
+
+void MethodCompiler::EmitStoreDalvikRetValReg(char shorty, JTypeSpace space,
+ llvm::Value* new_value) {
+ EmitStoreDalvikRetValReg(GetJTypeFromShorty(shorty), space, new_value);
+}
+
+
// TODO: Use high-level IR to do this
bool MethodCompiler::EmitInlineJavaIntrinsic(const std::string& callee_method_name,
const std::vector<llvm::Value*>& args,
@@ -4139,18 +4169,7 @@
break;
case Instruction::INSTANCE_OF:
- may_throw_exception = true;
- if (dec_insn.vA == this_reg_idx) {
- modify_this = true;
- }
- break;
-
case Instruction::ARRAY_LENGTH:
- if (dec_insn.vA == this_reg_idx) {
- modify_this = true;
- }
- break;
-
case Instruction::NEW_INSTANCE:
case Instruction::NEW_ARRAY:
may_throw_exception = true;