diff options
| author | 2012-11-02 09:58:19 -0700 | |
|---|---|---|
| committer | 2012-11-14 15:45:03 -0800 | |
| commit | 8e950c117975d23f50ed7e32ca5db01a813c25d0 (patch) | |
| tree | 2d4363de95db34aae624ff90929d4ec215ac63cd /src/compiler_llvm | |
| parent | 8bb8e8653b4c3ad5d87863f98ffec5f95a96c1fa (diff) | |
Simple debugging support for portable path.
Change-Id: Ibdc33b8d7f644c091fdb3ba3ce2ba45804bc4078
Diffstat (limited to 'src/compiler_llvm')
| -rw-r--r-- | src/compiler_llvm/art_module.ll | 1 | ||||
| -rw-r--r-- | src/compiler_llvm/dalvik_reg.cc | 24 | ||||
| -rw-r--r-- | src/compiler_llvm/dalvik_reg.h | 3 | ||||
| -rw-r--r-- | src/compiler_llvm/gbc_expander.cc | 50 | ||||
| -rw-r--r-- | src/compiler_llvm/ir_builder.cc | 5 | ||||
| -rw-r--r-- | src/compiler_llvm/ir_builder.h | 2 | ||||
| -rw-r--r-- | src/compiler_llvm/jni_compiler.cc | 2 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 50 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.h | 3 |
9 files changed, 108 insertions, 32 deletions
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll index 3c3c90bfe0..1c04dc836c 100644 --- a/src/compiler_llvm/art_module.ll +++ b/src/compiler_llvm/art_module.ll @@ -26,6 +26,7 @@ , i32 ; Line number for stack backtrace , i32 ; Number of references ; [0 x %JavaObject*] ; References + ; [0 x i32] ; VRegs } declare void @__art_type_list(%JavaObject*, %ShadowFrame*) diff --git a/src/compiler_llvm/dalvik_reg.cc b/src/compiler_llvm/dalvik_reg.cc index c3263ae951..dc73e75333 100644 --- a/src/compiler_llvm/dalvik_reg.cc +++ b/src/compiler_llvm/dalvik_reg.cc @@ -27,9 +27,9 @@ using namespace art::compiler_llvm; // Dalvik Register //---------------------------------------------------------------------------- -DalvikReg::DalvikReg(MethodCompiler& method_compiler, const std::string& name) +DalvikReg::DalvikReg(MethodCompiler& method_compiler, const std::string& name, llvm::Value* vreg) : method_compiler_(&method_compiler), irb_(method_compiler.GetIRBuilder()), - reg_name_(name), reg_32_(NULL), reg_64_(NULL), reg_obj_(NULL) { + reg_name_(name), reg_32_(NULL), reg_64_(NULL), reg_obj_(NULL), vreg_(vreg) { } @@ -118,10 +118,6 @@ llvm::Value* DalvikReg::GetValue(JType jty, JTypeSpace space) { return NULL; } break; - - default: - LOG(FATAL) << "Couldn't GetValue of JType " << jty; - return NULL; } if (jty == kFloat || jty == kDouble) { @@ -141,13 +137,13 @@ void DalvikReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) { switch (space) { case kReg: case kField: - irb_.CreateStore(value, GetAddr(jty), kTBAARegister); - return; + break; case kAccurate: case kArray: switch (jty) { case kVoid: + LOG(FATAL) << "Dalvik register with void type has no value"; break; case kBoolean: @@ -155,7 +151,7 @@ void DalvikReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) { // 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), kTBAARegister); + value = RegCat1ZExt(value); break; case kByte: @@ -163,7 +159,7 @@ void DalvikReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) { // 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), kTBAARegister); + value = RegCat1SExt(value); break; case kInt: @@ -171,13 +167,19 @@ void DalvikReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) { case kFloat: case kDouble: case kObject: - irb_.CreateStore(value, GetAddr(jty), kTBAARegister); break; default: LOG(FATAL) << "Unknown java type: " << jty; } } + + irb_.CreateStore(value, GetAddr(jty), kTBAARegister); + if (vreg_ != NULL) { + irb_.CreateStore(value, + irb_.CreateBitCast(vreg_, value->getType()->getPointerTo()), + kTBAAShadowFrame); + } } diff --git a/src/compiler_llvm/dalvik_reg.h b/src/compiler_llvm/dalvik_reg.h index f9507710bb..ac0f421e75 100644 --- a/src/compiler_llvm/dalvik_reg.h +++ b/src/compiler_llvm/dalvik_reg.h @@ -39,7 +39,7 @@ class DalvikReg { static char GetRegCategoryNamePrefix(RegCategory reg_cat); - DalvikReg(MethodCompiler& method_compiler, const std::string& name); + DalvikReg(MethodCompiler& method_compiler, const std::string& name, llvm::Value* vreg); ~DalvikReg(); @@ -70,6 +70,7 @@ class DalvikReg { llvm::Value* reg_32_; llvm::Value* reg_64_; llvm::Value* reg_obj_; + llvm::Value* vreg_; }; } // namespace compiler_llvm diff --git a/src/compiler_llvm/gbc_expander.cc b/src/compiler_llvm/gbc_expander.cc index 18cef411c3..c0943978d0 100644 --- a/src/compiler_llvm/gbc_expander.cc +++ b/src/compiler_llvm/gbc_expander.cc @@ -60,7 +60,6 @@ class GBCExpanderPass : public llvm::FunctionPass { private: llvm::AllocaInst* shadow_frame_; llvm::Value* old_shadow_frame_; - uint16_t num_shadow_frame_refs_; private: art::Compiler* compiler_; @@ -217,10 +216,12 @@ class GBCExpanderPass : public llvm::FunctionPass { llvm::Value* Expand_DivRem(llvm::CallInst& call_inst, bool is_div, JType op_jty); - void Expand_AllocaShadowFrame(llvm::Value* num_entry_value); + void Expand_AllocaShadowFrame(llvm::Value* num_entry_value, llvm::Value* num_vregs_value); void Expand_SetShadowFrameEntry(llvm::Value* obj, llvm::Value* entry_idx); + void Expand_SetVReg(llvm::Value* entry_idx, llvm::Value* obj); + void Expand_PopShadowFrame(); void Expand_UpdateDexPC(llvm::Value* dex_pc_value); @@ -326,7 +327,7 @@ class GBCExpanderPass : public llvm::FunctionPass { GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb) : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb), context_(irb.getContext()), rtb_(irb.Runtime()), - shadow_frame_(NULL), old_shadow_frame_(NULL), num_shadow_frame_refs_(0), + shadow_frame_(NULL), old_shadow_frame_(NULL), compiler_(NULL), dex_file_(NULL), code_item_(NULL), oat_compilation_unit_(NULL), method_idx_(-1u), func_(NULL), changed_(false) @@ -336,7 +337,7 @@ class GBCExpanderPass : public llvm::FunctionPass { art::Compiler* compiler, art::OatCompilationUnit* oat_compilation_unit) : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb), context_(irb.getContext()), rtb_(irb.Runtime()), - shadow_frame_(NULL), old_shadow_frame_(NULL), num_shadow_frame_refs_(0), + shadow_frame_(NULL), old_shadow_frame_(NULL), compiler_(compiler), dex_file_(oat_compilation_unit->GetDexFile()), code_item_(oat_compilation_unit->GetCodeItem()), @@ -366,7 +367,6 @@ bool GBCExpanderPass::runOnFunction(llvm::Function& func) { // Setup rewrite context shadow_frame_ = NULL; old_shadow_frame_ = NULL; - num_shadow_frame_refs_ = 0; func_ = &func; changed_ = false; // Assume unchanged @@ -1092,14 +1092,17 @@ llvm::Value* GBCExpanderPass::Expand_DivRem(llvm::CallInst& call_inst, return result; } -void GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_entry_value) { +void GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_entry_value, + llvm::Value* num_vregs_value) { // Most of the codes refer to MethodCompiler::EmitPrologueAllocShadowFrame and // MethodCompiler::EmitPushShadowFrame - num_shadow_frame_refs_ = + uint16_t num_shadow_frame_refs = llvm::cast<llvm::ConstantInt>(num_entry_value)->getZExtValue(); + uint16_t num_vregs = + llvm::cast<llvm::ConstantInt>(num_vregs_value)->getZExtValue(); llvm::StructType* shadow_frame_type = - irb_.getShadowFrameTy(num_shadow_frame_refs_); + irb_.getShadowFrameTy(num_shadow_frame_refs, num_vregs); shadow_frame_ = irb_.CreateAlloca(shadow_frame_type); @@ -1126,14 +1129,15 @@ void GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_entry_value) { llvm::Value* result = rtb_.EmitPushShadowFrame(shadow_frame_upcast, method_object_addr, - num_shadow_frame_refs_, - 0); + num_shadow_frame_refs, + num_vregs); irb_.CreateStore(result, old_shadow_frame_, kTBAARegister); return; } +// TODO: We will remove ShadowFrameEntry later, so I just copy/paste from ShadowFrameEntry. void GBCExpanderPass::Expand_SetShadowFrameEntry(llvm::Value* obj, llvm::Value* entry_idx) { DCHECK(shadow_frame_ != NULL); @@ -1154,6 +1158,24 @@ void GBCExpanderPass::Expand_SetShadowFrameEntry(llvm::Value* obj, return; } +void GBCExpanderPass::Expand_SetVReg(llvm::Value* entry_idx, + llvm::Value* value) { + DCHECK(shadow_frame_ != NULL); + + llvm::Value* gep_index[] = { + irb_.getInt32(0), // No pointer displacement + irb_.getInt32(2), // VRegs + entry_idx // Pointer field + }; + + llvm::Value* vreg_addr = irb_.CreateGEP(shadow_frame_, gep_index); + + irb_.CreateStore(value, + irb_.CreateBitCast(vreg_addr, value->getType()->getPointerTo()), + kTBAAShadowFrame); + return; +} + void GBCExpanderPass::Expand_PopShadowFrame() { #if defined(ART_USE_PORTABLE_COMPILER) if (old_shadow_frame_ == NULL) { @@ -3455,7 +3477,8 @@ GBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id, //==- Shadow Frame -----------------------------------------------------==// case IntrinsicHelper::AllocaShadowFrame: { - Expand_AllocaShadowFrame(call_inst.getArgOperand(0)); + Expand_AllocaShadowFrame(call_inst.getArgOperand(0), + call_inst.getArgOperand(1)); return NULL; } case IntrinsicHelper::SetShadowFrameEntry: { @@ -3463,6 +3486,11 @@ GBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id, call_inst.getArgOperand(1)); return NULL; } + case IntrinsicHelper::SetVReg: { + Expand_SetVReg(call_inst.getArgOperand(0), + call_inst.getArgOperand(1)); + return NULL; + } case IntrinsicHelper::PopShadowFrame: { Expand_PopShadowFrame(); return NULL; diff --git a/src/compiler_llvm/ir_builder.cc b/src/compiler_llvm/ir_builder.cc index 8ee4f3ede8..b271002df4 100644 --- a/src/compiler_llvm/ir_builder.cc +++ b/src/compiler_llvm/ir_builder.cc @@ -151,8 +151,8 @@ llvm::Type* IRBuilder::getJTypeInArraySpace(JType jty) { } -llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t sirt_size) { - std::string name(StringPrintf("ShadowFrame%u", sirt_size)); +llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t sirt_size, uint32_t vreg_size) { + std::string name(StringPrintf("ShadowFrame%u_vreg%u", sirt_size, vreg_size)); // Try to find the existing struct type definition if (llvm::Type* type = module_->getTypeByName(name)) { @@ -164,6 +164,7 @@ llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t sirt_size) { llvm::Type* elem_types[] = { art_frame_type_, llvm::ArrayType::get(jobject_type_, sirt_size), + llvm::ArrayType::get(getInt32Ty(), vreg_size), }; return llvm::StructType::create(elem_types, name); diff --git a/src/compiler_llvm/ir_builder.h b/src/compiler_llvm/ir_builder.h index 5df9831abc..cc0bc8e801 100644 --- a/src/compiler_llvm/ir_builder.h +++ b/src/compiler_llvm/ir_builder.h @@ -315,7 +315,7 @@ class IRBuilder : public LLVMIRBuilder { return getJLongTy(); } - llvm::StructType* getShadowFrameTy(uint32_t sirt_size); + llvm::StructType* getShadowFrameTy(uint32_t sirt_size, uint32_t vreg_size); //-------------------------------------------------------------------------- diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc index 7001ec3051..d5a7869d00 100644 --- a/src/compiler_llvm/jni_compiler.cc +++ b/src/compiler_llvm/jni_compiler.cc @@ -101,7 +101,7 @@ CompiledMethod* JniCompiler::Compile() { } // Shadow stack - llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(sirt_size); + llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(sirt_size, 0); llvm::AllocaInst* shadow_frame_ = irb_.CreateAlloca(shadow_frame_type); // Store the dex pc diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc index fea0c72a75..f09553cf06 100644 --- a/src/compiler_llvm/method_compiler.cc +++ b/src/compiler_llvm/method_compiler.cc @@ -175,7 +175,7 @@ void MethodCompiler::EmitPrologue() { #if !defined(NDEBUG) name = StringPrintf("%u", r); #endif - regs_[r] = new DalvikReg(*this, name); + regs_[r] = new DalvikReg(*this, name, GetVRegEntry(r)); // Cache shadow frame entry address shadow_frame_entries_[r] = GetShadowFrameEntry(r); @@ -185,7 +185,7 @@ void MethodCompiler::EmitPrologue() { #if !defined(NDEBUG) name = "_res"; #endif - retval_reg_.reset(new DalvikReg(*this, name)); + retval_reg_.reset(new DalvikReg(*this, name, NULL)); // Store argument to dalvik register irb_.SetInsertPoint(basic_block_reg_arg_init_); @@ -284,7 +284,8 @@ void MethodCompiler::EmitPrologueAllocShadowFrame() { } } - llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(num_shadow_frame_refs_); + llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(num_shadow_frame_refs_, + code_item_->registers_size_); shadow_frame_ = irb_.CreateAlloca(shadow_frame_type); // Alloca a pointer to old shadow frame @@ -3802,6 +3803,43 @@ llvm::Value* MethodCompiler::GetShadowFrameEntry(uint32_t reg_idx) { } +// TODO: We will remove ShadowFrameEntry later, so I just copy/paste from ShadowFrameEntry. +llvm::Value* MethodCompiler::GetVRegEntry(uint32_t reg_idx) { + if (!compiler_->IsDebuggingSupported()) { + return NULL; + } + + if (!method_info_.need_shadow_frame_entry) { + return NULL; + } + + std::string reg_name; + +#if !defined(NDEBUG) + StringAppendF(®_name, "v%u", reg_idx); +#endif + + // Save current IR builder insert point + llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP(); + + irb_.SetInsertPoint(basic_block_shadow_frame_); + + llvm::Value* gep_index[] = { + irb_.getInt32(0), // No pointer displacement + irb_.getInt32(2), // VRegs + irb_.getInt32(reg_idx) // Pointer field + }; + + llvm::Value* reg_addr = irb_.CreateGEP(shadow_frame_, gep_index, 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::EmitPushShadowFrame(bool is_inline) { if (!method_info_.need_shadow_frame) { return; @@ -3819,11 +3857,13 @@ void MethodCompiler::EmitPushShadowFrame(bool is_inline) { llvm::Value* result; if (is_inline) { result = irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr, - num_shadow_frame_refs_, 0); + num_shadow_frame_refs_, + code_item_->registers_size_); } else { DCHECK(num_shadow_frame_refs_ == 0); result = irb_.Runtime().EmitPushShadowFrameNoInline(shadow_frame_upcast, method_object_addr, - num_shadow_frame_refs_, 0); + num_shadow_frame_refs_, + code_item_->registers_size_); } irb_.CreateStore(result, old_shadow_frame_, kTBAARegister); } diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h index 0b6fcfd79d..02c3d6a476 100644 --- a/src/compiler_llvm/method_compiler.h +++ b/src/compiler_llvm/method_compiler.h @@ -90,6 +90,8 @@ class MethodCompiler { llvm::Value* GetShadowFrameEntry(uint32_t reg_idx); + llvm::Value* GetVRegEntry(uint32_t reg_idx); + private: void CreateFunction(); @@ -460,6 +462,7 @@ class MethodCompiler { std::vector<DalvikReg*> regs_; std::vector<llvm::Value*> shadow_frame_entries_; + std::vector<llvm::Value*> vregs_; std::vector<int32_t> reg_to_shadow_frame_index_; UniquePtr<DalvikReg> retval_reg_; |