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/dalvik_reg.cc b/src/compiler_llvm/dalvik_reg.cc
index e19067f..c3263ae 100644
--- a/src/compiler_llvm/dalvik_reg.cc
+++ b/src/compiler_llvm/dalvik_reg.cc
@@ -23,62 +23,13 @@
using namespace art::compiler_llvm;
-namespace {
-
- class DalvikLocalVarReg : public DalvikReg {
- public:
- DalvikLocalVarReg(MethodCompiler& method_compiler, uint32_t reg_idx);
-
- virtual void SetValue(JType jty, JTypeSpace space, llvm::Value* value);
-
- virtual ~DalvikLocalVarReg();
-
- private:
- virtual llvm::Value* GetRawAddr(JType jty, JTypeSpace space);
-
- private:
- uint32_t reg_idx_;
- llvm::Value* reg_32_;
- llvm::Value* reg_64_;
- llvm::Value* reg_obj_;
- llvm::Value* reg_shadow_frame_;
- };
-
- class DalvikRetValReg : public DalvikReg {
- public:
- DalvikRetValReg(MethodCompiler& method_compiler);
-
- virtual ~DalvikRetValReg();
-
- private:
- virtual llvm::Value* GetRawAddr(JType jty, JTypeSpace space);
-
- private:
- llvm::Value* reg_32_;
- llvm::Value* reg_64_;
- llvm::Value* reg_obj_;
- };
-
-} // anonymous namespace
-
-
//----------------------------------------------------------------------------
// Dalvik Register
//----------------------------------------------------------------------------
-DalvikReg* DalvikReg::CreateLocalVarReg(MethodCompiler& method_compiler,
- uint32_t reg_idx) {
- return new DalvikLocalVarReg(method_compiler, reg_idx);
-}
-
-
-DalvikReg* DalvikReg::CreateRetValReg(MethodCompiler& method_compiler) {
- return new DalvikRetValReg(method_compiler);
-}
-
-
-DalvikReg::DalvikReg(MethodCompiler& method_compiler)
-: method_compiler_(&method_compiler), irb_(method_compiler.GetIRBuilder()) {
+DalvikReg::DalvikReg(MethodCompiler& method_compiler, const std::string& name)
+: method_compiler_(&method_compiler), irb_(method_compiler.GetIRBuilder()),
+ reg_name_(name), reg_32_(NULL), reg_64_(NULL), reg_obj_(NULL) {
}
@@ -133,7 +84,7 @@
switch (space) {
case kReg:
case kField:
- value = irb_.CreateLoad(GetAddr(jty, space), kTBAARegister);
+ value = irb_.CreateLoad(GetAddr(jty), kTBAARegister);
break;
case kAccurate:
@@ -150,7 +101,7 @@
// NOTE: In array type space, boolean is truncated from i32 to i8, while
// in accurate type space, boolean is truncated from i32 to i1.
// For the other cases, array type space is equal to accurate type space.
- value = RegCat1Trunc(irb_.CreateLoad(GetAddr(jty, space), kTBAARegister),
+ value = RegCat1Trunc(irb_.CreateLoad(GetAddr(jty), kTBAARegister),
irb_.getJType(jty, space));
break;
@@ -159,7 +110,7 @@
case kFloat:
case kDouble:
case kObject:
- value = irb_.CreateLoad(GetAddr(jty, space), kTBAARegister);
+ value = irb_.CreateLoad(GetAddr(jty), kTBAARegister);
break;
default:
@@ -190,7 +141,7 @@
switch (space) {
case kReg:
case kField:
- irb_.CreateStore(value, GetAddr(jty, space), kTBAARegister);
+ irb_.CreateStore(value, GetAddr(jty), kTBAARegister);
return;
case kAccurate:
@@ -204,7 +155,7 @@
// NOTE: In accurate type space, we have to zero extend boolean from
// i1 to i32, and char from i16 to i32. In array type space, we have
// to zero extend boolean from i8 to i32, and char from i16 to i32.
- irb_.CreateStore(RegCat1ZExt(value), GetAddr(jty, space), kTBAARegister);
+ irb_.CreateStore(RegCat1ZExt(value), GetAddr(jty), kTBAARegister);
break;
case kByte:
@@ -212,7 +163,7 @@
// NOTE: In accurate type space, we have to signed extend byte from
// i8 to i32, and short from i16 to i32. In array type space, we have
// to sign extend byte from i8 to i32, and short from i16 to i32.
- irb_.CreateStore(RegCat1SExt(value), GetAddr(jty, space), kTBAARegister);
+ irb_.CreateStore(RegCat1SExt(value), GetAddr(jty), kTBAARegister);
break;
case kInt:
@@ -220,7 +171,7 @@
case kFloat:
case kDouble:
case kObject:
- irb_.CreateStore(value, GetAddr(jty, space), kTBAARegister);
+ irb_.CreateStore(value, GetAddr(jty), kTBAARegister);
break;
default:
@@ -230,94 +181,23 @@
}
-llvm::Value* DalvikReg::GetAddr(JType jty, JTypeSpace space) {
- return GetRawAddr(jty, space);
-}
-
-
-//----------------------------------------------------------------------------
-// Dalvik Local Variable Register
-//----------------------------------------------------------------------------
-
-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_shadow_frame_(NULL) {
-}
-
-
-DalvikLocalVarReg::~DalvikLocalVarReg() {
-}
-
-
-void DalvikLocalVarReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) {
- DalvikReg::SetValue(jty, space, value);
-
- if (jty == kObject && reg_shadow_frame_ != NULL) {
- irb_.CreateStore(value, reg_shadow_frame_, kTBAAShadowFrame);
- }
-}
-
-
-llvm::Value* DalvikLocalVarReg::GetRawAddr(JType jty, JTypeSpace space) {
+llvm::Value* DalvikReg::GetAddr(JType jty) {
switch (GetRegCategoryFromJType(jty)) {
case kRegCat1nr:
if (reg_32_ == NULL) {
- reg_32_ = method_compiler_->AllocDalvikLocalVarReg(kRegCat1nr, reg_idx_);
+ reg_32_ = method_compiler_->AllocDalvikReg(kRegCat1nr, reg_name_);
}
return reg_32_;
case kRegCat2:
if (reg_64_ == NULL) {
- reg_64_ = method_compiler_->AllocDalvikLocalVarReg(kRegCat2, reg_idx_);
+ reg_64_ = method_compiler_->AllocDalvikReg(kRegCat2, reg_name_);
}
return reg_64_;
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_;
-
- default:
- LOG(FATAL) << "Unexpected register category: "
- << GetRegCategoryFromJType(jty);
- return NULL;
- }
-}
-
-
-//----------------------------------------------------------------------------
-// Dalvik Returned Value Temporary Register
-//----------------------------------------------------------------------------
-
-DalvikRetValReg::DalvikRetValReg(MethodCompiler& method_compiler)
-: DalvikReg(method_compiler), reg_32_(NULL), reg_64_(NULL), reg_obj_(NULL) {
-}
-
-
-DalvikRetValReg::~DalvikRetValReg() {
-}
-
-
-llvm::Value* DalvikRetValReg::GetRawAddr(JType jty, JTypeSpace space) {
- switch (GetRegCategoryFromJType(jty)) {
- case kRegCat1nr:
- if (reg_32_ == NULL) {
- reg_32_ = method_compiler_->AllocDalvikRetValReg(kRegCat1nr);
- }
- return reg_32_;
-
- case kRegCat2:
- if (reg_64_ == NULL) {
- reg_64_ = method_compiler_->AllocDalvikRetValReg(kRegCat2);
- }
- return reg_64_;
-
- case kRegObject:
- if (reg_obj_ == NULL) {
- reg_obj_ = method_compiler_->AllocDalvikRetValReg(kRegObject);
+ reg_obj_ = method_compiler_->AllocDalvikReg(kRegObject, reg_name_);
}
return reg_obj_;
diff --git a/src/compiler_llvm/dalvik_reg.h b/src/compiler_llvm/dalvik_reg.h
index 7356c87..f950771 100644
--- a/src/compiler_llvm/dalvik_reg.h
+++ b/src/compiler_llvm/dalvik_reg.h
@@ -20,6 +20,7 @@
#include "backend_types.h"
#include <stdint.h>
+#include <string>
namespace llvm {
class Type;
@@ -34,16 +35,13 @@
class DalvikReg {
public:
- static DalvikReg* CreateLocalVarReg(MethodCompiler& method_compiler,
- uint32_t reg_idx);
-
- static DalvikReg* CreateRetValReg(MethodCompiler& method_compiler);
-
static llvm::Type* GetRegCategoryEquivSizeTy(IRBuilder& irb, RegCategory reg_cat);
static char GetRegCategoryNamePrefix(RegCategory reg_cat);
- virtual ~DalvikReg();
+ DalvikReg(MethodCompiler& method_compiler, const std::string& name);
+
+ ~DalvikReg();
llvm::Value* GetValue(JType jty, JTypeSpace space);
@@ -51,28 +49,27 @@
return GetValue(GetJTypeFromShorty(shorty), space);
}
- virtual void SetValue(JType jty, JTypeSpace space, llvm::Value* value);
+ void SetValue(JType jty, JTypeSpace space, llvm::Value* value);
void SetValue(char shorty, JTypeSpace space, llvm::Value* value) {
return SetValue(GetJTypeFromShorty(shorty), space, value);
}
- protected:
- DalvikReg(MethodCompiler& method_compiler);
-
private:
- llvm::Value* GetAddr(JType jty, JTypeSpace space);
+ llvm::Value* GetAddr(JType jty);
llvm::Value* RegCat1SExt(llvm::Value* value);
llvm::Value* RegCat1ZExt(llvm::Value* value);
llvm::Value* RegCat1Trunc(llvm::Value* value, llvm::Type* ty);
- virtual llvm::Value* GetRawAddr(JType jty, JTypeSpace space) = 0;
-
- protected:
MethodCompiler* method_compiler_;
IRBuilder& irb_;
+
+ std::string reg_name_;
+ llvm::Value* reg_32_;
+ llvm::Value* reg_64_;
+ llvm::Value* reg_obj_;
};
} // namespace compiler_llvm
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;
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index 50411a1..6de50ed 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -18,7 +18,6 @@
#define ART_SRC_COMPILER_LLVM_METHOD_COMPILER_H_
#include "backend_types.h"
-#include "dalvik_reg.h"
#include "dex_file.h"
#include "dex_instruction.h"
#include "invoke_type.h"
@@ -59,6 +58,7 @@
class CompilationUnit;
class CompilerLLVM;
+class DalvikReg;
class IRBuilder;
class MethodCompiler {
@@ -81,11 +81,9 @@
// Register helper function
- llvm::Value* AllocDalvikLocalVarReg(RegCategory cat, uint32_t reg_idx);
+ llvm::Value* AllocDalvikReg(RegCategory cat, const std::string& name);
- llvm::Value* AllocShadowFrameEntry(uint32_t reg_idx);
-
- llvm::Value* AllocDalvikRetValReg(RegCategory cat);
+ llvm::Value* GetShadowFrameEntry(uint32_t reg_idx);
private:
@@ -395,43 +393,23 @@
// Register helper function
- llvm::Value* EmitLoadDalvikReg(uint32_t reg_idx, JType jty,
- JTypeSpace space) {
- return regs_[reg_idx]->GetValue(jty, space);
- }
+ llvm::Value* EmitLoadDalvikReg(uint32_t reg_idx, JType jty, JTypeSpace space);
- llvm::Value* EmitLoadDalvikReg(uint32_t reg_idx, char shorty,
- JTypeSpace space) {
- return EmitLoadDalvikReg(reg_idx, GetJTypeFromShorty(shorty), space);
- }
+ llvm::Value* EmitLoadDalvikReg(uint32_t reg_idx, char shorty, JTypeSpace space);
void EmitStoreDalvikReg(uint32_t reg_idx, JType jty,
- JTypeSpace space, llvm::Value* new_value) {
- regs_[reg_idx]->SetValue(jty, space, new_value);
- }
+ JTypeSpace space, llvm::Value* new_value);
void EmitStoreDalvikReg(uint32_t reg_idx, char shorty,
- JTypeSpace space, llvm::Value* new_value) {
- EmitStoreDalvikReg(reg_idx, GetJTypeFromShorty(shorty), space, new_value);
- }
+ JTypeSpace space, llvm::Value* new_value);
- llvm::Value* EmitLoadDalvikRetValReg(JType jty, JTypeSpace space) {
- return retval_reg_->GetValue(jty, space);
- }
+ llvm::Value* EmitLoadDalvikRetValReg(JType jty, JTypeSpace space);
- llvm::Value* EmitLoadDalvikRetValReg(char shorty, JTypeSpace space) {
- return EmitLoadDalvikRetValReg(GetJTypeFromShorty(shorty), space);
- }
+ llvm::Value* EmitLoadDalvikRetValReg(char shorty, JTypeSpace space);
- void EmitStoreDalvikRetValReg(JType jty, JTypeSpace space,
- llvm::Value* new_value) {
- retval_reg_->SetValue(jty, space, new_value);
- }
+ void EmitStoreDalvikRetValReg(JType jty, JTypeSpace space, llvm::Value* new_value);
- void EmitStoreDalvikRetValReg(char shorty, JTypeSpace space,
- llvm::Value* new_value) {
- EmitStoreDalvikRetValReg(GetJTypeFromShorty(shorty), space, new_value);
- }
+ void EmitStoreDalvikRetValReg(char shorty, JTypeSpace space, llvm::Value* new_value);
// TODO: Use high-level IR to do this
bool EmitInlineJavaIntrinsic(const std::string& callee_method_name,
@@ -477,6 +455,7 @@
llvm::Function* func_;
std::vector<DalvikReg*> regs_;
+ std::vector<llvm::Value*> shadow_frame_entries_;
std::vector<int32_t> reg_to_shadow_frame_index_;
UniquePtr<DalvikReg> retval_reg_;