Reduce shadow frame size.
Change-Id: Ifbd5cb38d0666a1f5db1abe7da36ff86a93f87b5
diff --git a/src/compiler_llvm/dalvik_reg.cc b/src/compiler_llvm/dalvik_reg.cc
index ab5cc40..84da907 100644
--- a/src/compiler_llvm/dalvik_reg.cc
+++ b/src/compiler_llvm/dalvik_reg.cc
@@ -246,9 +246,7 @@
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.";
+ if (jty == kObject && reg_shadow_frame_ != NULL) {
irb_.CreateStore(value, reg_shadow_frame_, kTBAAShadowFrame);
}
}
diff --git a/src/compiler_llvm/inferred_reg_category_map.cc b/src/compiler_llvm/inferred_reg_category_map.cc
index 04acd6f..2403750 100644
--- a/src/compiler_llvm/inferred_reg_category_map.cc
+++ b/src/compiler_llvm/inferred_reg_category_map.cc
@@ -28,7 +28,7 @@
InferredRegCategoryMap::InferredRegCategoryMap(uint32_t insns_size,
uint8_t regs_size)
-: registers_size_(regs_size), lines_(insns_size, NULL) {
+: registers_size_(regs_size), lines_(insns_size, NULL), can_be_object_(regs_size) {
}
InferredRegCategoryMap::~InferredRegCategoryMap() {
@@ -55,6 +55,14 @@
}
}
+bool InferredRegCategoryMap::IsRegCanBeObject(uint16_t reg_idx) const {
+ return can_be_object_[reg_idx];
+}
+
+void InferredRegCategoryMap::SetRegCanBeObject(uint16_t reg_idx) {
+ can_be_object_[reg_idx] = true;
+}
+
bool InferredRegCategoryMap::
operator==(InferredRegCategoryMap const& rhs) const {
diff --git a/src/compiler_llvm/inferred_reg_category_map.h b/src/compiler_llvm/inferred_reg_category_map.h
index 7b3501b..7f4082d 100644
--- a/src/compiler_llvm/inferred_reg_category_map.h
+++ b/src/compiler_llvm/inferred_reg_category_map.h
@@ -67,6 +67,9 @@
RegCategory GetRegCategory(uint32_t dex_pc, uint16_t reg_idx) const;
void SetRegCategory(uint32_t dex_pc, uint16_t reg_idx, RegCategory cat);
+ bool IsRegCanBeObject(uint16_t reg_idx) const;
+ void SetRegCanBeObject(uint16_t reg_idx);
+
bool operator==(InferredRegCategoryMap const& rhs) const;
bool operator!=(InferredRegCategoryMap const& rhs) const;
@@ -75,6 +78,8 @@
std::vector<RegCategoryLine*> lines_;
+ std::vector<bool> can_be_object_;
+
DISALLOW_COPY_AND_ASSIGN(InferredRegCategoryMap);
};
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);
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index e1465dc..e815e3b 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -374,6 +374,10 @@
RegCategory GetInferredRegCategory(uint32_t dex_pc, uint16_t reg);
+ InferredRegCategoryMap const* GetInferredRegCategoryMap();
+
+ bool IsRegCanBeObject(uint16_t reg_idx);
+
// Basic block helper functions
llvm::BasicBlock* GetBasicBlock(uint32_t dex_pc);
@@ -453,6 +457,7 @@
llvm::Function* func_;
std::vector<DalvikReg*> regs_;
+ std::vector<int32_t> reg_to_shadow_frame_index_;
UniquePtr<DalvikReg> retval_reg_;
llvm::BasicBlock* basic_block_stack_overflow_;