diff options
Diffstat (limited to 'compiler/dex')
-rw-r--r-- | compiler/dex/frontend.cc | 2 | ||||
-rw-r--r-- | compiler/dex/frontend.h | 2 | ||||
-rw-r--r-- | compiler/dex/mir_optimization.cc | 3 | ||||
-rw-r--r-- | compiler/dex/portable/mir_to_gbc.cc | 2003 | ||||
-rw-r--r-- | compiler/dex/portable/mir_to_gbc.h | 241 | ||||
-rw-r--r-- | compiler/dex/quick/quick_compiler.cc | 12 | ||||
-rw-r--r-- | compiler/dex/verification_results.cc | 12 |
7 files changed, 3 insertions, 2272 deletions
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc index fb5dc9c1b2..dd8b4c8a3d 100644 --- a/compiler/dex/frontend.cc +++ b/compiler/dex/frontend.cc @@ -69,8 +69,6 @@ static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes // (1 << kDebugShowNops) | // (1 << kDebugCountOpcodes) | // (1 << kDebugDumpCheckStats) | - // (1 << kDebugDumpBitcodeFile) | - // (1 << kDebugVerifyBitcode) | // (1 << kDebugShowSummaryMemoryUsage) | // (1 << kDebugShowFilterStats) | // (1 << kDebugTimings) | diff --git a/compiler/dex/frontend.h b/compiler/dex/frontend.h index 1145818789..4266535053 100644 --- a/compiler/dex/frontend.h +++ b/compiler/dex/frontend.h @@ -70,8 +70,6 @@ enum debugControlVector { kDebugShowNops, kDebugCountOpcodes, kDebugDumpCheckStats, - kDebugDumpBitcodeFile, - kDebugVerifyBitcode, kDebugShowSummaryMemoryUsage, kDebugShowFilterStats, kDebugTimings, diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc index f78b39f648..6e9844cb7f 100644 --- a/compiler/dex/mir_optimization.cc +++ b/compiler/dex/mir_optimization.cc @@ -552,8 +552,7 @@ bool MIRGraph::BasicBlockOpt(BasicBlock* bb) { // Is this the select pattern? // TODO: flesh out support for Mips. NOTE: llvm's select op doesn't quite work here. // TUNING: expand to support IF_xx compare & branches - if (!cu_->compiler->IsPortable() && - (cu_->instruction_set == kArm64 || cu_->instruction_set == kThumb2 || + if ((cu_->instruction_set == kArm64 || cu_->instruction_set == kThumb2 || cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64) && IsInstructionIfCcZ(mir->dalvikInsn.opcode)) { BasicBlock* ft = GetBasicBlock(bb->fall_through); diff --git a/compiler/dex/portable/mir_to_gbc.cc b/compiler/dex/portable/mir_to_gbc.cc deleted file mode 100644 index ba255e0a76..0000000000 --- a/compiler/dex/portable/mir_to_gbc.cc +++ /dev/null @@ -1,2003 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "object_utils.h" - -#include <llvm/ADT/DepthFirstIterator.h> -#include <llvm/Analysis/Verifier.h> -#include <llvm/Bitcode/ReaderWriter.h> -#include <llvm/IR/Instruction.h> -#include <llvm/IR/Instructions.h> -#include <llvm/IR/Metadata.h> -#include <llvm/IR/Type.h> -#include <llvm/Support/Casting.h> -#include <llvm/Support/InstIterator.h> -#include <llvm/Support/ToolOutputFile.h> - -#include "dex/compiler_internals.h" -#include "dex/dataflow_iterator-inl.h" -#include "dex/frontend.h" -#include "llvm/ir_builder.h" -#include "llvm/llvm_compilation_unit.h" -#include "llvm/utils_llvm.h" -#include "mir_to_gbc.h" -#include "thread-inl.h" - -const char* kLabelFormat = "%c0x%x_%d"; -const char kInvalidBlock = 0xff; -const char kNormalBlock = 'L'; -const char kCatchBlock = 'C'; - -namespace art { -namespace llvm { -::llvm::Module* makeLLVMModuleContents(::llvm::Module* module); -} - -LLVMInfo::LLVMInfo() { - // Create context, module, intrinsic helper & ir builder - llvm_context_.reset(new ::llvm::LLVMContext()); - llvm_module_ = new ::llvm::Module("art", *llvm_context_); - ::llvm::StructType::create(*llvm_context_, "JavaObject"); - art::llvm::makeLLVMModuleContents(llvm_module_); - intrinsic_helper_.reset(new art::llvm::IntrinsicHelper(*llvm_context_, *llvm_module_)); - ir_builder_.reset(new art::llvm::IRBuilder(*llvm_context_, *llvm_module_, *intrinsic_helper_)); -} - -LLVMInfo::~LLVMInfo() { -} - -::llvm::BasicBlock* MirConverter::GetLLVMBlock(int id) { - return id_to_block_map_.Get(id); -} - -::llvm::Value* MirConverter::GetLLVMValue(int s_reg) { - return llvm_values_[s_reg]; -} - -void MirConverter::SetVregOnValue(::llvm::Value* val, int s_reg) { - // Set vreg for debugging - art::llvm::IntrinsicHelper::IntrinsicId id = art::llvm::IntrinsicHelper::SetVReg; - ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(id); - int v_reg = mir_graph_->SRegToVReg(s_reg); - ::llvm::Value* table_slot = irb_->getInt32(v_reg); - ::llvm::Value* args[] = { table_slot, val }; - irb_->CreateCall(func, args); -} - -// Replace the placeholder value with the real definition -void MirConverter::DefineValueOnly(::llvm::Value* val, int s_reg) { - ::llvm::Value* placeholder = GetLLVMValue(s_reg); - if (placeholder == NULL) { - // This can happen on instruction rewrite on verification failure - LOG(WARNING) << "Null placeholder"; - return; - } - placeholder->replaceAllUsesWith(val); - val->takeName(placeholder); - llvm_values_[s_reg] = val; - ::llvm::Instruction* inst = ::llvm::dyn_cast< ::llvm::Instruction>(placeholder); - DCHECK(inst != NULL); - inst->eraseFromParent(); -} - -void MirConverter::DefineValue(::llvm::Value* val, int s_reg) { - DefineValueOnly(val, s_reg); - SetVregOnValue(val, s_reg); -} - -::llvm::Type* MirConverter::LlvmTypeFromLocRec(RegLocation loc) { - ::llvm::Type* res = NULL; - if (loc.wide) { - if (loc.fp) - res = irb_->getDoubleTy(); - else - res = irb_->getInt64Ty(); - } else { - if (loc.fp) { - res = irb_->getFloatTy(); - } else { - if (loc.ref) - res = irb_->getJObjectTy(); - else - res = irb_->getInt32Ty(); - } - } - return res; -} - -void MirConverter::InitIR() { - if (llvm_info_ == NULL) { - CompilerTls* tls = cu_->compiler_driver->GetTls(); - CHECK(tls != NULL); - llvm_info_ = static_cast<LLVMInfo*>(tls->GetLLVMInfo()); - if (llvm_info_ == NULL) { - llvm_info_ = new LLVMInfo(); - tls->SetLLVMInfo(llvm_info_); - } - } - context_ = llvm_info_->GetLLVMContext(); - module_ = llvm_info_->GetLLVMModule(); - intrinsic_helper_ = llvm_info_->GetIntrinsicHelper(); - irb_ = llvm_info_->GetIRBuilder(); -} - -::llvm::BasicBlock* MirConverter::FindCaseTarget(uint32_t vaddr) { - BasicBlock* bb = mir_graph_->FindBlock(vaddr); - DCHECK(bb != NULL); - return GetLLVMBlock(bb->id); -} - -void MirConverter::ConvertPackedSwitch(BasicBlock* bb, MIR* mir, - int32_t table_offset, RegLocation rl_src) { - const Instruction::PackedSwitchPayload* payload = - reinterpret_cast<const Instruction::PackedSwitchPayload*>( - mir_graph_->GetTable(mir, table_offset)); - - ::llvm::Value* value = GetLLVMValue(rl_src.orig_sreg); - - ::llvm::SwitchInst* sw = - irb_->CreateSwitch(value, GetLLVMBlock(bb->fall_through), - payload->case_count); - - for (uint16_t i = 0; i < payload->case_count; ++i) { - ::llvm::BasicBlock* llvm_bb = - FindCaseTarget(current_dalvik_offset_ + payload->targets[i]); - sw->addCase(irb_->getInt32(payload->first_key + i), llvm_bb); - } - ::llvm::MDNode* switch_node = - ::llvm::MDNode::get(*context_, irb_->getInt32(table_offset)); - sw->setMetadata("SwitchTable", switch_node); - bb->taken = NullBasicBlockId; - bb->fall_through = NullBasicBlockId; -} - -void MirConverter::ConvertSparseSwitch(BasicBlock* bb, MIR* mir, - int32_t table_offset, RegLocation rl_src) { - const Instruction::SparseSwitchPayload* payload = - reinterpret_cast<const Instruction::SparseSwitchPayload*>( - mir_graph_->GetTable(mir, table_offset)); - - const int32_t* keys = payload->GetKeys(); - const int32_t* targets = payload->GetTargets(); - - ::llvm::Value* value = GetLLVMValue(rl_src.orig_sreg); - - ::llvm::SwitchInst* sw = - irb_->CreateSwitch(value, GetLLVMBlock(bb->fall_through), - payload->case_count); - - for (size_t i = 0; i < payload->case_count; ++i) { - ::llvm::BasicBlock* llvm_bb = - FindCaseTarget(current_dalvik_offset_ + targets[i]); - sw->addCase(irb_->getInt32(keys[i]), llvm_bb); - } - ::llvm::MDNode* switch_node = - ::llvm::MDNode::get(*context_, irb_->getInt32(table_offset)); - sw->setMetadata("SwitchTable", switch_node); - bb->taken = NullBasicBlockId; - bb->fall_through = NullBasicBlockId; -} - -void MirConverter::ConvertSget(int32_t field_index, - art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest) { - ::llvm::Constant* field_idx = irb_->getInt32(field_index); - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::Value* res = irb_->CreateCall(intr, field_idx); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertSput(int32_t field_index, - art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src) { - ::llvm::SmallVector< ::llvm::Value*, 2> args; - args.push_back(irb_->getInt32(field_index)); - args.push_back(GetLLVMValue(rl_src.orig_sreg)); - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - irb_->CreateCall(intr, args); -} - -void MirConverter::ConvertFillArrayData(int32_t offset, RegLocation rl_array) { - art::llvm::IntrinsicHelper::IntrinsicId id; - id = art::llvm::IntrinsicHelper::HLFillArrayData; - ::llvm::SmallVector< ::llvm::Value*, 2> args; - args.push_back(irb_->getInt32(offset)); - args.push_back(GetLLVMValue(rl_array.orig_sreg)); - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - irb_->CreateCall(intr, args); -} - -::llvm::Value* MirConverter::EmitConst(::llvm::ArrayRef< ::llvm::Value*> src, - RegLocation loc) { - art::llvm::IntrinsicHelper::IntrinsicId id; - if (loc.wide) { - if (loc.fp) { - id = art::llvm::IntrinsicHelper::ConstDouble; - } else { - id = art::llvm::IntrinsicHelper::ConstLong; - } - } else { - if (loc.fp) { - id = art::llvm::IntrinsicHelper::ConstFloat; - } else if (loc.ref) { - id = art::llvm::IntrinsicHelper::ConstObj; - } else { - id = art::llvm::IntrinsicHelper::ConstInt; - } - } - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - return irb_->CreateCall(intr, src); -} - -void MirConverter::EmitPopShadowFrame() { - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction( - art::llvm::IntrinsicHelper::PopShadowFrame); - irb_->CreateCall(intr); -} - -::llvm::Value* MirConverter::EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src, - RegLocation loc) { - art::llvm::IntrinsicHelper::IntrinsicId id; - if (loc.wide) { - if (loc.fp) { - id = art::llvm::IntrinsicHelper::CopyDouble; - } else { - id = art::llvm::IntrinsicHelper::CopyLong; - } - } else { - if (loc.fp) { - id = art::llvm::IntrinsicHelper::CopyFloat; - } else if (loc.ref) { - id = art::llvm::IntrinsicHelper::CopyObj; - } else { - id = art::llvm::IntrinsicHelper::CopyInt; - } - } - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - return irb_->CreateCall(intr, src); -} - -void MirConverter::ConvertMoveException(RegLocation rl_dest) { - ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction( - art::llvm::IntrinsicHelper::GetException); - ::llvm::Value* res = irb_->CreateCall(func); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertThrow(RegLocation rl_src) { - ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg); - ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction( - art::llvm::IntrinsicHelper::HLThrowException); - irb_->CreateCall(func, src); -} - -void MirConverter::ConvertMonitorEnterExit(int opt_flags, - art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_src) { - ::llvm::SmallVector< ::llvm::Value*, 2> args; - args.push_back(irb_->getInt32(opt_flags)); - args.push_back(GetLLVMValue(rl_src.orig_sreg)); - ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(id); - irb_->CreateCall(func, args); -} - -void MirConverter::ConvertArrayLength(int opt_flags, - RegLocation rl_dest, RegLocation rl_src) { - ::llvm::SmallVector< ::llvm::Value*, 2> args; - args.push_back(irb_->getInt32(opt_flags)); - args.push_back(GetLLVMValue(rl_src.orig_sreg)); - ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction( - art::llvm::IntrinsicHelper::OptArrayLength); - ::llvm::Value* res = irb_->CreateCall(func, args); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::EmitSuspendCheck() { - art::llvm::IntrinsicHelper::IntrinsicId id = - art::llvm::IntrinsicHelper::CheckSuspend; - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - irb_->CreateCall(intr); -} - -::llvm::Value* MirConverter::ConvertCompare(ConditionCode cc, - ::llvm::Value* src1, ::llvm::Value* src2) { - ::llvm::Value* res = NULL; - DCHECK_EQ(src1->getType(), src2->getType()); - switch (cc) { - case kCondEq: res = irb_->CreateICmpEQ(src1, src2); break; - case kCondNe: res = irb_->CreateICmpNE(src1, src2); break; - case kCondLt: res = irb_->CreateICmpSLT(src1, src2); break; - case kCondGe: res = irb_->CreateICmpSGE(src1, src2); break; - case kCondGt: res = irb_->CreateICmpSGT(src1, src2); break; - case kCondLe: res = irb_->CreateICmpSLE(src1, src2); break; - default: LOG(FATAL) << "Unexpected cc value " << cc; - } - return res; -} - -void MirConverter::ConvertCompareAndBranch(BasicBlock* bb, MIR* mir, - ConditionCode cc, RegLocation rl_src1, RegLocation rl_src2) { - if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= mir->offset) { - EmitSuspendCheck(); - } - ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg); - ::llvm::Value* src2 = GetLLVMValue(rl_src2.orig_sreg); - ::llvm::Value* cond_value = ConvertCompare(cc, src1, src2); - cond_value->setName(StringPrintf("t%d", temp_name_++)); - irb_->CreateCondBr(cond_value, GetLLVMBlock(bb->taken), - GetLLVMBlock(bb->fall_through)); - // Don't redo the fallthrough branch in the BB driver - bb->fall_through = NullBasicBlockId; -} - -void MirConverter::ConvertCompareZeroAndBranch(BasicBlock* bb, - MIR* mir, ConditionCode cc, RegLocation rl_src1) { - if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= mir->offset) { - EmitSuspendCheck(); - } - ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg); - ::llvm::Value* src2; - if (rl_src1.ref) { - src2 = irb_->getJNull(); - } else { - src2 = irb_->getInt32(0); - } - ::llvm::Value* cond_value = ConvertCompare(cc, src1, src2); - irb_->CreateCondBr(cond_value, GetLLVMBlock(bb->taken), - GetLLVMBlock(bb->fall_through)); - // Don't redo the fallthrough branch in the BB driver - bb->fall_through = NullBasicBlockId; -} - -::llvm::Value* MirConverter::GenDivModOp(bool is_div, bool is_long, - ::llvm::Value* src1, ::llvm::Value* src2) { - art::llvm::IntrinsicHelper::IntrinsicId id; - if (is_long) { - if (is_div) { - id = art::llvm::IntrinsicHelper::DivLong; - } else { - id = art::llvm::IntrinsicHelper::RemLong; - } - } else { - if (is_div) { - id = art::llvm::IntrinsicHelper::DivInt; - } else { - id = art::llvm::IntrinsicHelper::RemInt; - } - } - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::SmallVector< ::llvm::Value*, 2>args; - args.push_back(src1); - args.push_back(src2); - return irb_->CreateCall(intr, args); -} - -::llvm::Value* MirConverter::GenArithOp(OpKind op, bool is_long, - ::llvm::Value* src1, ::llvm::Value* src2) { - ::llvm::Value* res = NULL; - switch (op) { - case kOpAdd: res = irb_->CreateAdd(src1, src2); break; - case kOpSub: res = irb_->CreateSub(src1, src2); break; - case kOpRsub: res = irb_->CreateSub(src2, src1); break; - case kOpMul: res = irb_->CreateMul(src1, src2); break; - case kOpOr: res = irb_->CreateOr(src1, src2); break; - case kOpAnd: res = irb_->CreateAnd(src1, src2); break; - case kOpXor: res = irb_->CreateXor(src1, src2); break; - case kOpDiv: res = GenDivModOp(true, is_long, src1, src2); break; - case kOpRem: res = GenDivModOp(false, is_long, src1, src2); break; - case kOpLsl: res = irb_->CreateShl(src1, src2); break; - case kOpLsr: res = irb_->CreateLShr(src1, src2); break; - case kOpAsr: res = irb_->CreateAShr(src1, src2); break; - default: - LOG(FATAL) << "Invalid op " << op; - } - return res; -} - -void MirConverter::ConvertFPArithOp(OpKind op, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2) { - ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg); - ::llvm::Value* src2 = GetLLVMValue(rl_src2.orig_sreg); - ::llvm::Value* res = NULL; - switch (op) { - case kOpAdd: res = irb_->CreateFAdd(src1, src2); break; - case kOpSub: res = irb_->CreateFSub(src1, src2); break; - case kOpMul: res = irb_->CreateFMul(src1, src2); break; - case kOpDiv: res = irb_->CreateFDiv(src1, src2); break; - case kOpRem: res = irb_->CreateFRem(src1, src2); break; - default: - LOG(FATAL) << "Invalid op " << op; - } - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::SmallVector< ::llvm::Value*, 2>args; - args.push_back(GetLLVMValue(rl_src1.orig_sreg)); - args.push_back(GetLLVMValue(rl_src2.orig_sreg)); - ::llvm::Value* res = irb_->CreateCall(intr, args); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_src, int shift_amount) { - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::SmallVector< ::llvm::Value*, 2>args; - args.push_back(GetLLVMValue(rl_src.orig_sreg)); - args.push_back(irb_->getInt32(shift_amount)); - ::llvm::Value* res = irb_->CreateCall(intr, args); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertArithOp(OpKind op, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2) { - ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg); - ::llvm::Value* src2 = GetLLVMValue(rl_src2.orig_sreg); - DCHECK_EQ(src1->getType(), src2->getType()); - ::llvm::Value* res = GenArithOp(op, rl_dest.wide, src1, src2); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertArithOpLit(OpKind op, RegLocation rl_dest, - RegLocation rl_src1, int32_t imm) { - ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg); - ::llvm::Value* src2 = irb_->getInt32(imm); - ::llvm::Value* res = GenArithOp(op, rl_dest.wide, src1, src2); - DefineValue(res, rl_dest.orig_sreg); -} - -/* - * Process arguments for invoke. Note: this code is also used to - * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE. - * The requirements are similar. - */ -void MirConverter::ConvertInvoke(BasicBlock* bb, MIR* mir, - InvokeType invoke_type, bool is_range, bool is_filled_new_array) { - CallInfo* info = mir_graph_->NewMemCallInfo(bb, mir, invoke_type, is_range); - ::llvm::SmallVector< ::llvm::Value*, 10> args; - // Insert the invoke_type - args.push_back(irb_->getInt32(static_cast<int>(invoke_type))); - // Insert the method_idx - args.push_back(irb_->getInt32(info->index)); - // Insert the optimization flags - args.push_back(irb_->getInt32(info->opt_flags)); - // Now, insert the actual arguments - for (int i = 0; i < info->num_arg_words;) { - ::llvm::Value* val = GetLLVMValue(info->args[i].orig_sreg); - args.push_back(val); - i += info->args[i].wide ? 2 : 1; - } - /* - * Choose the invoke return type based on actual usage. Note: may - * be different than shorty. For example, if a function return value - * is not used, we'll treat this as a void invoke. - */ - art::llvm::IntrinsicHelper::IntrinsicId id; - if (is_filled_new_array) { - id = art::llvm::IntrinsicHelper::HLFilledNewArray; - } else if (info->result.location == kLocInvalid) { - id = art::llvm::IntrinsicHelper::HLInvokeVoid; - } else { - if (info->result.wide) { - if (info->result.fp) { - id = art::llvm::IntrinsicHelper::HLInvokeDouble; - } else { - id = art::llvm::IntrinsicHelper::HLInvokeLong; - } - } else if (info->result.ref) { - id = art::llvm::IntrinsicHelper::HLInvokeObj; - } else if (info->result.fp) { - id = art::llvm::IntrinsicHelper::HLInvokeFloat; - } else { - id = art::llvm::IntrinsicHelper::HLInvokeInt; - } - } - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::Value* res = irb_->CreateCall(intr, args); - if (info->result.location != kLocInvalid) { - DefineValue(res, info->result.orig_sreg); - } -} - -void MirConverter::ConvertConstObject(uint32_t idx, - art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest) { - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::Value* index = irb_->getInt32(idx); - ::llvm::Value* res = irb_->CreateCall(intr, index); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertCheckCast(uint32_t type_idx, RegLocation rl_src) { - art::llvm::IntrinsicHelper::IntrinsicId id; - id = art::llvm::IntrinsicHelper::HLCheckCast; - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::SmallVector< ::llvm::Value*, 2> args; - args.push_back(irb_->getInt32(type_idx)); - args.push_back(GetLLVMValue(rl_src.orig_sreg)); - irb_->CreateCall(intr, args); -} - -void MirConverter::ConvertNewInstance(uint32_t type_idx, RegLocation rl_dest) { - art::llvm::IntrinsicHelper::IntrinsicId id; - id = art::llvm::IntrinsicHelper::NewInstance; - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::Value* index = irb_->getInt32(type_idx); - ::llvm::Value* res = irb_->CreateCall(intr, index); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertNewArray(uint32_t type_idx, - RegLocation rl_dest, RegLocation rl_src) { - art::llvm::IntrinsicHelper::IntrinsicId id; - id = art::llvm::IntrinsicHelper::NewArray; - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::SmallVector< ::llvm::Value*, 2> args; - args.push_back(irb_->getInt32(type_idx)); - args.push_back(GetLLVMValue(rl_src.orig_sreg)); - ::llvm::Value* res = irb_->CreateCall(intr, args); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertAget(int opt_flags, - art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index) { - ::llvm::SmallVector< ::llvm::Value*, 3> args; - args.push_back(irb_->getInt32(opt_flags)); - args.push_back(GetLLVMValue(rl_array.orig_sreg)); - args.push_back(GetLLVMValue(rl_index.orig_sreg)); - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::Value* res = irb_->CreateCall(intr, args); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertAput(int opt_flags, - art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_src, RegLocation rl_array, RegLocation rl_index) { - ::llvm::SmallVector< ::llvm::Value*, 4> args; - args.push_back(irb_->getInt32(opt_flags)); - args.push_back(GetLLVMValue(rl_src.orig_sreg)); - args.push_back(GetLLVMValue(rl_array.orig_sreg)); - args.push_back(GetLLVMValue(rl_index.orig_sreg)); - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - irb_->CreateCall(intr, args); -} - -void MirConverter::ConvertIget(int opt_flags, - art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_obj, int field_index) { - ::llvm::SmallVector< ::llvm::Value*, 3> args; - args.push_back(irb_->getInt32(opt_flags)); - args.push_back(GetLLVMValue(rl_obj.orig_sreg)); - args.push_back(irb_->getInt32(field_index)); - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::Value* res = irb_->CreateCall(intr, args); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertIput(int opt_flags, - art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_src, RegLocation rl_obj, int field_index) { - ::llvm::SmallVector< ::llvm::Value*, 4> args; - args.push_back(irb_->getInt32(opt_flags)); - args.push_back(GetLLVMValue(rl_src.orig_sreg)); - args.push_back(GetLLVMValue(rl_obj.orig_sreg)); - args.push_back(irb_->getInt32(field_index)); - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - irb_->CreateCall(intr, args); -} - -void MirConverter::ConvertInstanceOf(uint32_t type_idx, - RegLocation rl_dest, RegLocation rl_src) { - art::llvm::IntrinsicHelper::IntrinsicId id; - id = art::llvm::IntrinsicHelper::InstanceOf; - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::SmallVector< ::llvm::Value*, 2> args; - args.push_back(irb_->getInt32(type_idx)); - args.push_back(GetLLVMValue(rl_src.orig_sreg)); - ::llvm::Value* res = irb_->CreateCall(intr, args); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertIntToLong(RegLocation rl_dest, RegLocation rl_src) { - ::llvm::Value* res = irb_->CreateSExt(GetLLVMValue(rl_src.orig_sreg), - irb_->getInt64Ty()); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertLongToInt(RegLocation rl_dest, RegLocation rl_src) { - ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg); - ::llvm::Value* res = irb_->CreateTrunc(src, irb_->getInt32Ty()); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertFloatToDouble(RegLocation rl_dest, RegLocation rl_src) { - ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg); - ::llvm::Value* res = irb_->CreateFPExt(src, irb_->getDoubleTy()); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertDoubleToFloat(RegLocation rl_dest, RegLocation rl_src) { - ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg); - ::llvm::Value* res = irb_->CreateFPTrunc(src, irb_->getFloatTy()); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) { - DCHECK_EQ(rl_src1.fp, rl_src2.fp); - DCHECK_EQ(rl_src1.wide, rl_src2.wide); - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::SmallVector< ::llvm::Value*, 2> args; - args.push_back(GetLLVMValue(rl_src1.orig_sreg)); - args.push_back(GetLLVMValue(rl_src2.orig_sreg)); - ::llvm::Value* res = irb_->CreateCall(intr, args); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertIntNarrowing(RegLocation rl_dest, RegLocation rl_src, - art::llvm::IntrinsicHelper::IntrinsicId id) { - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::Value* res = - irb_->CreateCall(intr, GetLLVMValue(rl_src.orig_sreg)); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertNeg(RegLocation rl_dest, RegLocation rl_src) { - ::llvm::Value* res = irb_->CreateNeg(GetLLVMValue(rl_src.orig_sreg)); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertIntToFP(::llvm::Type* ty, RegLocation rl_dest, - RegLocation rl_src) { - ::llvm::Value* res = - irb_->CreateSIToFP(GetLLVMValue(rl_src.orig_sreg), ty); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, - RegLocation rl_src) { - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::Value* res = irb_->CreateCall(intr, GetLLVMValue(rl_src.orig_sreg)); - DefineValue(res, rl_dest.orig_sreg); -} - - -void MirConverter::ConvertNegFP(RegLocation rl_dest, RegLocation rl_src) { - ::llvm::Value* res = - irb_->CreateFNeg(GetLLVMValue(rl_src.orig_sreg)); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::ConvertNot(RegLocation rl_dest, RegLocation rl_src) { - ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg); - ::llvm::Value* res = irb_->CreateXor(src, static_cast<uint64_t>(-1)); - DefineValue(res, rl_dest.orig_sreg); -} - -void MirConverter::EmitConstructorBarrier() { - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction( - art::llvm::IntrinsicHelper::ConstructorBarrier); - irb_->CreateCall(intr); -} - -/* - * Target-independent code generation. Use only high-level - * load/store utilities here, or target-dependent genXX() handlers - * when necessary. - */ -bool MirConverter::ConvertMIRNode(MIR* mir, BasicBlock* bb, - ::llvm::BasicBlock* llvm_bb) { - bool res = false; // Assume success - RegLocation rl_src[3]; - RegLocation rl_dest = mir_graph_->GetBadLoc(); - Instruction::Code opcode = mir->dalvikInsn.opcode; - int op_val = opcode; - uint32_t vB = mir->dalvikInsn.vB; - uint32_t vC = mir->dalvikInsn.vC; - int opt_flags = mir->optimization_flags; - - if (cu_->verbose) { - if (!IsPseudoMirOp(op_val)) { - LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << op_val; - } else { - LOG(INFO) << mir_graph_->extended_mir_op_names_[op_val - kMirOpFirst] << " 0x" << std::hex << op_val; - } - } - - /* Prep Src and Dest locations */ - int next_sreg = 0; - int next_loc = 0; - uint64_t attrs = MirGraph::GetDataFlowAttributes(opcode); - rl_src[0] = rl_src[1] = rl_src[2] = mir_graph_->GetBadLoc(); - if (attrs & DF_UA) { - if (attrs & DF_A_WIDE) { - rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg); - next_sreg+= 2; - } else { - rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg); - next_sreg++; - } - } - if (attrs & DF_UB) { - if (attrs & DF_B_WIDE) { - rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg); - next_sreg+= 2; - } else { - rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg); - next_sreg++; - } - } - if (attrs & DF_UC) { - if (attrs & DF_C_WIDE) { - rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg); - } else { - rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg); - } - } - if (attrs & DF_DA) { - if (attrs & DF_A_WIDE) { - rl_dest = mir_graph_->GetDestWide(mir); - } else { - rl_dest = mir_graph_->GetDest(mir); - } - } - - switch (opcode) { - case Instruction::NOP: - break; - - case Instruction::MOVE: - case Instruction::MOVE_OBJECT: - case Instruction::MOVE_16: - case Instruction::MOVE_OBJECT_16: - case Instruction::MOVE_OBJECT_FROM16: - case Instruction::MOVE_FROM16: - case Instruction::MOVE_WIDE: - case Instruction::MOVE_WIDE_16: - case Instruction::MOVE_WIDE_FROM16: { - /* - * Moves/copies are meaningless in pure SSA register form, - * but we need to preserve them for the conversion back into - * MIR (at least until we stop using the Dalvik register maps). - * Insert a dummy intrinsic copy call, which will be recognized - * by the quick path and removed by the portable path. - */ - ::llvm::Value* src = GetLLVMValue(rl_src[0].orig_sreg); - ::llvm::Value* res = EmitCopy(src, rl_dest); - DefineValue(res, rl_dest.orig_sreg); - } - break; - - case Instruction::CONST: - case Instruction::CONST_4: - case Instruction::CONST_16: { - ::llvm::Constant* imm_value = irb_->getJInt(vB); - ::llvm::Value* res = EmitConst(imm_value, rl_dest); - DefineValue(res, rl_dest.orig_sreg); - } - break; - - case Instruction::CONST_WIDE_16: - case Instruction::CONST_WIDE_32: { - // Sign extend to 64 bits - int64_t imm = static_cast<int32_t>(vB); - ::llvm::Constant* imm_value = irb_->getJLong(imm); - ::llvm::Value* res = EmitConst(imm_value, rl_dest); - DefineValue(res, rl_dest.orig_sreg); - } - break; - - case Instruction::CONST_HIGH16: { - ::llvm::Constant* imm_value = irb_->getJInt(vB << 16); - ::llvm::Value* res = EmitConst(imm_value, rl_dest); - DefineValue(res, rl_dest.orig_sreg); - } - break; - - case Instruction::CONST_WIDE: { - ::llvm::Constant* imm_value = - irb_->getJLong(mir->dalvikInsn.vB_wide); - ::llvm::Value* res = EmitConst(imm_value, rl_dest); - DefineValue(res, rl_dest.orig_sreg); - } - break; - case Instruction::CONST_WIDE_HIGH16: { - int64_t imm = static_cast<int64_t>(vB) << 48; - ::llvm::Constant* imm_value = irb_->getJLong(imm); - ::llvm::Value* res = EmitConst(imm_value, rl_dest); - DefineValue(res, rl_dest.orig_sreg); - } - break; - - case Instruction::SPUT_OBJECT: - ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputObject, - rl_src[0]); - break; - case Instruction::SPUT: - if (rl_src[0].fp) { - ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputFloat, - rl_src[0]); - } else { - ConvertSput(vB, art::llvm::IntrinsicHelper::HLSput, rl_src[0]); - } - break; - case Instruction::SPUT_BOOLEAN: - ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputBoolean, - rl_src[0]); - break; - case Instruction::SPUT_BYTE: - ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputByte, rl_src[0]); - break; - case Instruction::SPUT_CHAR: - ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputChar, rl_src[0]); - break; - case Instruction::SPUT_SHORT: - ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputShort, rl_src[0]); - break; - case Instruction::SPUT_WIDE: - if (rl_src[0].fp) { - ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputDouble, - rl_src[0]); - } else { - ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputWide, - rl_src[0]); - } - break; - - case Instruction::SGET_OBJECT: - ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetObject, rl_dest); - break; - case Instruction::SGET: - if (rl_dest.fp) { - ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetFloat, rl_dest); - } else { - ConvertSget(vB, art::llvm::IntrinsicHelper::HLSget, rl_dest); - } - break; - case Instruction::SGET_BOOLEAN: - ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetBoolean, rl_dest); - break; - case Instruction::SGET_BYTE: - ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetByte, rl_dest); - break; - case Instruction::SGET_CHAR: - ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetChar, rl_dest); - break; - case Instruction::SGET_SHORT: - ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetShort, rl_dest); - break; - case Instruction::SGET_WIDE: - if (rl_dest.fp) { - ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetDouble, - rl_dest); - } else { - ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetWide, rl_dest); - } - break; - - case Instruction::RETURN_WIDE: - case Instruction::RETURN: - case Instruction::RETURN_OBJECT: { - if (!mir_graph_->MethodIsLeaf()) { - EmitSuspendCheck(); - } - EmitPopShadowFrame(); - irb_->CreateRet(GetLLVMValue(rl_src[0].orig_sreg)); - DCHECK(bb->terminated_by_return); - } - break; - - case Instruction::RETURN_VOID: { - if (((cu_->access_flags & kAccConstructor) != 0) && - cu_->compiler_driver->RequiresConstructorBarrier(Thread::Current(), - cu_->dex_file, - cu_->class_def_idx)) { - EmitConstructorBarrier(); - } - if (!mir_graph_->MethodIsLeaf()) { - EmitSuspendCheck(); - } - EmitPopShadowFrame(); - irb_->CreateRetVoid(); - DCHECK(bb->terminated_by_return); - } - break; - - case Instruction::IF_EQ: - ConvertCompareAndBranch(bb, mir, kCondEq, rl_src[0], rl_src[1]); - break; - case Instruction::IF_NE: - ConvertCompareAndBranch(bb, mir, kCondNe, rl_src[0], rl_src[1]); - break; - case Instruction::IF_LT: - ConvertCompareAndBranch(bb, mir, kCondLt, rl_src[0], rl_src[1]); - break; - case Instruction::IF_GE: - ConvertCompareAndBranch(bb, mir, kCondGe, rl_src[0], rl_src[1]); - break; - case Instruction::IF_GT: - ConvertCompareAndBranch(bb, mir, kCondGt, rl_src[0], rl_src[1]); - break; - case Instruction::IF_LE: - ConvertCompareAndBranch(bb, mir, kCondLe, rl_src[0], rl_src[1]); - break; - case Instruction::IF_EQZ: - ConvertCompareZeroAndBranch(bb, mir, kCondEq, rl_src[0]); - break; - case Instruction::IF_NEZ: - ConvertCompareZeroAndBranch(bb, mir, kCondNe, rl_src[0]); - break; - case Instruction::IF_LTZ: - ConvertCompareZeroAndBranch(bb, mir, kCondLt, rl_src[0]); - break; - case Instruction::IF_GEZ: - ConvertCompareZeroAndBranch(bb, mir, kCondGe, rl_src[0]); - break; - case Instruction::IF_GTZ: - ConvertCompareZeroAndBranch(bb, mir, kCondGt, rl_src[0]); - break; - case Instruction::IF_LEZ: - ConvertCompareZeroAndBranch(bb, mir, kCondLe, rl_src[0]); - break; - - case Instruction::GOTO: - case Instruction::GOTO_16: - case Instruction::GOTO_32: { - if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= bb->start_offset) { - EmitSuspendCheck(); - } - irb_->CreateBr(GetLLVMBlock(bb->taken)); - } - break; - - case Instruction::ADD_LONG: - case Instruction::ADD_LONG_2ADDR: - case Instruction::ADD_INT: - case Instruction::ADD_INT_2ADDR: - ConvertArithOp(kOpAdd, rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::SUB_LONG: - case Instruction::SUB_LONG_2ADDR: - case Instruction::SUB_INT: - case Instruction::SUB_INT_2ADDR: - ConvertArithOp(kOpSub, rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::MUL_LONG: - case Instruction::MUL_LONG_2ADDR: - case Instruction::MUL_INT: - case Instruction::MUL_INT_2ADDR: - ConvertArithOp(kOpMul, rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::DIV_LONG: - case Instruction::DIV_LONG_2ADDR: - case Instruction::DIV_INT: - case Instruction::DIV_INT_2ADDR: - ConvertArithOp(kOpDiv, rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::REM_LONG: - case Instruction::REM_LONG_2ADDR: - case Instruction::REM_INT: - case Instruction::REM_INT_2ADDR: - ConvertArithOp(kOpRem, rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::AND_LONG: - case Instruction::AND_LONG_2ADDR: - case Instruction::AND_INT: - case Instruction::AND_INT_2ADDR: - ConvertArithOp(kOpAnd, rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::OR_LONG: - case Instruction::OR_LONG_2ADDR: - case Instruction::OR_INT: - case Instruction::OR_INT_2ADDR: - ConvertArithOp(kOpOr, rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::XOR_LONG: - case Instruction::XOR_LONG_2ADDR: - case Instruction::XOR_INT: - case Instruction::XOR_INT_2ADDR: - ConvertArithOp(kOpXor, rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::SHL_LONG: - case Instruction::SHL_LONG_2ADDR: - ConvertShift(art::llvm::IntrinsicHelper::SHLLong, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::SHL_INT: - case Instruction::SHL_INT_2ADDR: - ConvertShift(art::llvm::IntrinsicHelper::SHLInt, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::SHR_LONG: - case Instruction::SHR_LONG_2ADDR: - ConvertShift(art::llvm::IntrinsicHelper::SHRLong, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::SHR_INT: - case Instruction::SHR_INT_2ADDR: - ConvertShift(art::llvm::IntrinsicHelper::SHRInt, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::USHR_LONG: - case Instruction::USHR_LONG_2ADDR: - ConvertShift(art::llvm::IntrinsicHelper::USHRLong, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::USHR_INT: - case Instruction::USHR_INT_2ADDR: - ConvertShift(art::llvm::IntrinsicHelper::USHRInt, - rl_dest, rl_src[0], rl_src[1]); - break; - - case Instruction::ADD_INT_LIT16: - case Instruction::ADD_INT_LIT8: - ConvertArithOpLit(kOpAdd, rl_dest, rl_src[0], vC); - break; - case Instruction::RSUB_INT: - case Instruction::RSUB_INT_LIT8: - ConvertArithOpLit(kOpRsub, rl_dest, rl_src[0], vC); - break; - case Instruction::MUL_INT_LIT16: - case Instruction::MUL_INT_LIT8: - ConvertArithOpLit(kOpMul, rl_dest, rl_src[0], vC); - break; - case Instruction::DIV_INT_LIT16: - case Instruction::DIV_INT_LIT8: - ConvertArithOpLit(kOpDiv, rl_dest, rl_src[0], vC); - break; - case Instruction::REM_INT_LIT16: - case Instruction::REM_INT_LIT8: - ConvertArithOpLit(kOpRem, rl_dest, rl_src[0], vC); - break; - case Instruction::AND_INT_LIT16: - case Instruction::AND_INT_LIT8: - ConvertArithOpLit(kOpAnd, rl_dest, rl_src[0], vC); - break; - case Instruction::OR_INT_LIT16: - case Instruction::OR_INT_LIT8: - ConvertArithOpLit(kOpOr, rl_dest, rl_src[0], vC); - break; - case Instruction::XOR_INT_LIT16: - case Instruction::XOR_INT_LIT8: - ConvertArithOpLit(kOpXor, rl_dest, rl_src[0], vC); - break; - case Instruction::SHL_INT_LIT8: - ConvertShiftLit(art::llvm::IntrinsicHelper::SHLInt, - rl_dest, rl_src[0], vC & 0x1f); - break; - case Instruction::SHR_INT_LIT8: - ConvertShiftLit(art::llvm::IntrinsicHelper::SHRInt, - rl_dest, rl_src[0], vC & 0x1f); - break; - case Instruction::USHR_INT_LIT8: - ConvertShiftLit(art::llvm::IntrinsicHelper::USHRInt, - rl_dest, rl_src[0], vC & 0x1f); - break; - - case Instruction::ADD_FLOAT: - case Instruction::ADD_FLOAT_2ADDR: - case Instruction::ADD_DOUBLE: - case Instruction::ADD_DOUBLE_2ADDR: - ConvertFPArithOp(kOpAdd, rl_dest, rl_src[0], rl_src[1]); - break; - - case Instruction::SUB_FLOAT: - case Instruction::SUB_FLOAT_2ADDR: - case Instruction::SUB_DOUBLE: - case Instruction::SUB_DOUBLE_2ADDR: - ConvertFPArithOp(kOpSub, rl_dest, rl_src[0], rl_src[1]); - break; - - case Instruction::MUL_FLOAT: - case Instruction::MUL_FLOAT_2ADDR: - case Instruction::MUL_DOUBLE: - case Instruction::MUL_DOUBLE_2ADDR: - ConvertFPArithOp(kOpMul, rl_dest, rl_src[0], rl_src[1]); - break; - - case Instruction::DIV_FLOAT: - case Instruction::DIV_FLOAT_2ADDR: - case Instruction::DIV_DOUBLE: - case Instruction::DIV_DOUBLE_2ADDR: - ConvertFPArithOp(kOpDiv, rl_dest, rl_src[0], rl_src[1]); - break; - - case Instruction::REM_FLOAT: - case Instruction::REM_FLOAT_2ADDR: - case Instruction::REM_DOUBLE: - case Instruction::REM_DOUBLE_2ADDR: - ConvertFPArithOp(kOpRem, rl_dest, rl_src[0], rl_src[1]); - break; - - case Instruction::INVOKE_STATIC: - ConvertInvoke(bb, mir, kStatic, false /*range*/, - false /* NewFilledArray */); - break; - case Instruction::INVOKE_STATIC_RANGE: - ConvertInvoke(bb, mir, kStatic, true /*range*/, - false /* NewFilledArray */); - break; - - case Instruction::INVOKE_DIRECT: - ConvertInvoke(bb, mir, kDirect, false /*range*/, - false /* NewFilledArray */); - break; - case Instruction::INVOKE_DIRECT_RANGE: - ConvertInvoke(bb, mir, kDirect, true /*range*/, - false /* NewFilledArray */); - break; - - case Instruction::INVOKE_VIRTUAL: - ConvertInvoke(bb, mir, kVirtual, false /*range*/, - false /* NewFilledArray */); - break; - case Instruction::INVOKE_VIRTUAL_RANGE: - ConvertInvoke(bb, mir, kVirtual, true /*range*/, - false /* NewFilledArray */); - break; - - case Instruction::INVOKE_SUPER: - ConvertInvoke(bb, mir, kSuper, false /*range*/, - false /* NewFilledArray */); - break; - case Instruction::INVOKE_SUPER_RANGE: - ConvertInvoke(bb, mir, kSuper, true /*range*/, - false /* NewFilledArray */); - break; - - case Instruction::INVOKE_INTERFACE: - ConvertInvoke(bb, mir, kInterface, false /*range*/, - false /* NewFilledArray */); - break; - case Instruction::INVOKE_INTERFACE_RANGE: - ConvertInvoke(bb, mir, kInterface, true /*range*/, - false /* NewFilledArray */); - break; - case Instruction::FILLED_NEW_ARRAY: - ConvertInvoke(bb, mir, kInterface, false /*range*/, - true /* NewFilledArray */); - break; - case Instruction::FILLED_NEW_ARRAY_RANGE: - ConvertInvoke(bb, mir, kInterface, true /*range*/, - true /* NewFilledArray */); - break; - - case Instruction::CONST_STRING: - case Instruction::CONST_STRING_JUMBO: - ConvertConstObject(vB, art::llvm::IntrinsicHelper::ConstString, - rl_dest); - break; - - case Instruction::CONST_CLASS: - ConvertConstObject(vB, art::llvm::IntrinsicHelper::ConstClass, - rl_dest); - break; - - case Instruction::CHECK_CAST: - ConvertCheckCast(vB, rl_src[0]); - break; - - case Instruction::NEW_INSTANCE: - ConvertNewInstance(vB, rl_dest); - break; - - case Instruction::MOVE_EXCEPTION: - ConvertMoveException(rl_dest); - break; - - case Instruction::THROW: - ConvertThrow(rl_src[0]); - /* - * If this throw is standalone, terminate. - * If it might rethrow, force termination - * of the following block. - */ - if (bb->fall_through == NullBasicBlockId) { - irb_->CreateUnreachable(); - } else { - mir_graph_->GetBasicBlock(bb->fall_through)->fall_through = NullBasicBlockId; - mir_graph_->GetBasicBlock(bb->fall_through)->taken = NullBasicBlockId; - } - break; - - case Instruction::MOVE_RESULT_WIDE: - case Instruction::MOVE_RESULT: - case Instruction::MOVE_RESULT_OBJECT: - /* - * All move_results should have been folded into the preceeding invoke. - */ - LOG(FATAL) << "Unexpected move_result"; - break; - - case Instruction::MONITOR_ENTER: - ConvertMonitorEnterExit(opt_flags, - art::llvm::IntrinsicHelper::MonitorEnter, - rl_src[0]); - break; - - case Instruction::MONITOR_EXIT: - ConvertMonitorEnterExit(opt_flags, - art::llvm::IntrinsicHelper::MonitorExit, - rl_src[0]); - break; - - case Instruction::ARRAY_LENGTH: - ConvertArrayLength(opt_flags, rl_dest, rl_src[0]); - break; - - case Instruction::NEW_ARRAY: - ConvertNewArray(vC, rl_dest, rl_src[0]); - break; - - case Instruction::INSTANCE_OF: - ConvertInstanceOf(vC, rl_dest, rl_src[0]); - break; - - case Instruction::AGET: - if (rl_dest.fp) { - ConvertAget(opt_flags, - art::llvm::IntrinsicHelper::HLArrayGetFloat, - rl_dest, rl_src[0], rl_src[1]); - } else { - ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGet, - rl_dest, rl_src[0], rl_src[1]); - } - break; - case Instruction::AGET_OBJECT: - ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetObject, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::AGET_BOOLEAN: - ConvertAget(opt_flags, - art::llvm::IntrinsicHelper::HLArrayGetBoolean, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::AGET_BYTE: - ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetByte, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::AGET_CHAR: - ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetChar, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::AGET_SHORT: - ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetShort, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::AGET_WIDE: - if (rl_dest.fp) { - ConvertAget(opt_flags, - art::llvm::IntrinsicHelper::HLArrayGetDouble, - rl_dest, rl_src[0], rl_src[1]); - } else { - ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetWide, - rl_dest, rl_src[0], rl_src[1]); - } - break; - - case Instruction::APUT: - if (rl_src[0].fp) { - ConvertAput(opt_flags, - art::llvm::IntrinsicHelper::HLArrayPutFloat, - rl_src[0], rl_src[1], rl_src[2]); - } else { - ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPut, - rl_src[0], rl_src[1], rl_src[2]); - } - break; - case Instruction::APUT_OBJECT: - ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutObject, - rl_src[0], rl_src[1], rl_src[2]); - break; - case Instruction::APUT_BOOLEAN: - ConvertAput(opt_flags, - art::llvm::IntrinsicHelper::HLArrayPutBoolean, - rl_src[0], rl_src[1], rl_src[2]); - break; - case Instruction::APUT_BYTE: - ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutByte, - rl_src[0], rl_src[1], rl_src[2]); - break; - case Instruction::APUT_CHAR: - ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutChar, - rl_src[0], rl_src[1], rl_src[2]); - break; - case Instruction::APUT_SHORT: - ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutShort, - rl_src[0], rl_src[1], rl_src[2]); - break; - case Instruction::APUT_WIDE: - if (rl_src[0].fp) { - ConvertAput(opt_flags, - art::llvm::IntrinsicHelper::HLArrayPutDouble, - rl_src[0], rl_src[1], rl_src[2]); - } else { - ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutWide, - rl_src[0], rl_src[1], rl_src[2]); - } - break; - - case Instruction::IGET: - if (rl_dest.fp) { - ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetFloat, - rl_dest, rl_src[0], vC); - } else { - ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGet, - rl_dest, rl_src[0], vC); - } - break; - case Instruction::IGET_OBJECT: - ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetObject, - rl_dest, rl_src[0], vC); - break; - case Instruction::IGET_BOOLEAN: - ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetBoolean, - rl_dest, rl_src[0], vC); - break; - case Instruction::IGET_BYTE: - ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetByte, - rl_dest, rl_src[0], vC); - break; - case Instruction::IGET_CHAR: - ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetChar, - rl_dest, rl_src[0], vC); - break; - case Instruction::IGET_SHORT: - ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetShort, - rl_dest, rl_src[0], vC); - break; - case Instruction::IGET_WIDE: - if (rl_dest.fp) { - ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetDouble, - rl_dest, rl_src[0], vC); - } else { - ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetWide, - rl_dest, rl_src[0], vC); - } - break; - case Instruction::IPUT: - if (rl_src[0].fp) { - ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutFloat, - rl_src[0], rl_src[1], vC); - } else { - ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPut, - rl_src[0], rl_src[1], vC); - } - break; - case Instruction::IPUT_OBJECT: - ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutObject, - rl_src[0], rl_src[1], vC); - break; - case Instruction::IPUT_BOOLEAN: - ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutBoolean, - rl_src[0], rl_src[1], vC); - break; - case Instruction::IPUT_BYTE: - ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutByte, - rl_src[0], rl_src[1], vC); - break; - case Instruction::IPUT_CHAR: - ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutChar, - rl_src[0], rl_src[1], vC); - break; - case Instruction::IPUT_SHORT: - ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutShort, - rl_src[0], rl_src[1], vC); - break; - case Instruction::IPUT_WIDE: - if (rl_src[0].fp) { - ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutDouble, - rl_src[0], rl_src[1], vC); - } else { - ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutWide, - rl_src[0], rl_src[1], vC); - } - break; - - case Instruction::FILL_ARRAY_DATA: - ConvertFillArrayData(vB, rl_src[0]); - break; - - case Instruction::LONG_TO_INT: - ConvertLongToInt(rl_dest, rl_src[0]); - break; - - case Instruction::INT_TO_LONG: - ConvertIntToLong(rl_dest, rl_src[0]); - break; - - case Instruction::INT_TO_CHAR: - ConvertIntNarrowing(rl_dest, rl_src[0], - art::llvm::IntrinsicHelper::IntToChar); - break; - case Instruction::INT_TO_BYTE: - ConvertIntNarrowing(rl_dest, rl_src[0], - art::llvm::IntrinsicHelper::IntToByte); - break; - case Instruction::INT_TO_SHORT: - ConvertIntNarrowing(rl_dest, rl_src[0], - art::llvm::IntrinsicHelper::IntToShort); - break; - - case Instruction::INT_TO_FLOAT: - case Instruction::LONG_TO_FLOAT: - ConvertIntToFP(irb_->getFloatTy(), rl_dest, rl_src[0]); - break; - - case Instruction::INT_TO_DOUBLE: - case Instruction::LONG_TO_DOUBLE: - ConvertIntToFP(irb_->getDoubleTy(), rl_dest, rl_src[0]); - break; - - case Instruction::FLOAT_TO_DOUBLE: - ConvertFloatToDouble(rl_dest, rl_src[0]); - break; - - case Instruction::DOUBLE_TO_FLOAT: - ConvertDoubleToFloat(rl_dest, rl_src[0]); - break; - - case Instruction::NEG_LONG: - case Instruction::NEG_INT: - ConvertNeg(rl_dest, rl_src[0]); - break; - - case Instruction::NEG_FLOAT: - case Instruction::NEG_DOUBLE: - ConvertNegFP(rl_dest, rl_src[0]); - break; - - case Instruction::NOT_LONG: - case Instruction::NOT_INT: - ConvertNot(rl_dest, rl_src[0]); - break; - - case Instruction::FLOAT_TO_INT: - ConvertFPToInt(art::llvm::IntrinsicHelper::F2I, rl_dest, rl_src[0]); - break; - - case Instruction::DOUBLE_TO_INT: - ConvertFPToInt(art::llvm::IntrinsicHelper::D2I, rl_dest, rl_src[0]); - break; - - case Instruction::FLOAT_TO_LONG: - ConvertFPToInt(art::llvm::IntrinsicHelper::F2L, rl_dest, rl_src[0]); - break; - - case Instruction::DOUBLE_TO_LONG: - ConvertFPToInt(art::llvm::IntrinsicHelper::D2L, rl_dest, rl_src[0]); - break; - - case Instruction::CMPL_FLOAT: - ConvertWideComparison(art::llvm::IntrinsicHelper::CmplFloat, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::CMPG_FLOAT: - ConvertWideComparison(art::llvm::IntrinsicHelper::CmpgFloat, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::CMPL_DOUBLE: - ConvertWideComparison(art::llvm::IntrinsicHelper::CmplDouble, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::CMPG_DOUBLE: - ConvertWideComparison(art::llvm::IntrinsicHelper::CmpgDouble, - rl_dest, rl_src[0], rl_src[1]); - break; - case Instruction::CMP_LONG: - ConvertWideComparison(art::llvm::IntrinsicHelper::CmpLong, - rl_dest, rl_src[0], rl_src[1]); - break; - - case Instruction::PACKED_SWITCH: - ConvertPackedSwitch(bb, vB, rl_src[0]); - break; - - case Instruction::SPARSE_SWITCH: - ConvertSparseSwitch(bb, vB, rl_src[0]); - break; - - default: - UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode; - res = true; - } - return res; -} // NOLINT(readability/fn_size) - -void MirConverter::SetDexOffset(int32_t offset) { - current_dalvik_offset_ = offset; - ::llvm::SmallVector< ::llvm::Value*, 1> array_ref; - array_ref.push_back(irb_->getInt32(offset)); - ::llvm::MDNode* node = ::llvm::MDNode::get(*context_, array_ref); - irb_->SetDexOffset(node); -} - -// Attach method info as metadata to special intrinsic -void MirConverter::SetMethodInfo() { - // We don't want dex offset on this - irb_->SetDexOffset(NULL); - art::llvm::IntrinsicHelper::IntrinsicId id; - id = art::llvm::IntrinsicHelper::MethodInfo; - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::Instruction* inst = irb_->CreateCall(intr); - ::llvm::SmallVector< ::llvm::Value*, 2> reg_info; - reg_info.push_back(irb_->getInt32(mir_graph_->GetNumOfInVRs())); - reg_info.push_back(irb_->getInt32(mir_graph_->GetNumOfLocalCodeVRs())); - reg_info.push_back(irb_->getInt32(mir_graph_->GetNumOfOutVRs())); - reg_info.push_back(irb_->getInt32(mir_graph_->GetNumUsedCompilerTemps())); - reg_info.push_back(irb_->getInt32(mir_graph_->GetNumSSARegs())); - ::llvm::MDNode* reg_info_node = ::llvm::MDNode::get(*context_, reg_info); - inst->setMetadata("RegInfo", reg_info_node); - SetDexOffset(current_dalvik_offset_); -} - -void MirConverter::HandlePhiNodes(BasicBlock* bb, ::llvm::BasicBlock* llvm_bb) { - SetDexOffset(bb->start_offset); - for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) { - int opcode = mir->dalvikInsn.opcode; - if (!IsPseudoMirOp(opcode)) { - // Stop after first non-pseudo MIR op. - continue; - } - if (opcode != kMirOpPhi) { - // Skip other mir Pseudos. - continue; - } - RegLocation rl_dest = mir_graph_->reg_location_[mir->ssa_rep->defs[0]]; - /* - * The Art compiler's Phi nodes only handle 32-bit operands, - * representing wide values using a matched set of Phi nodes - * for the lower and upper halves. In the llvm world, we only - * want a single Phi for wides. Here we will simply discard - * the Phi node representing the high word. - */ - if (rl_dest.high_word) { - continue; // No Phi node - handled via low word - } - BasicBlockId* incoming = mir->meta.phi_incoming; - ::llvm::Type* phi_type = - LlvmTypeFromLocRec(rl_dest); - ::llvm::PHINode* phi = irb_->CreatePHI(phi_type, mir->ssa_rep->num_uses); - for (int i = 0; i < mir->ssa_rep->num_uses; i++) { - RegLocation loc; - // Don't check width here. - loc = mir_graph_->GetRawSrc(mir, i); - DCHECK_EQ(rl_dest.wide, loc.wide); - DCHECK_EQ(rl_dest.wide & rl_dest.high_word, loc.wide & loc.high_word); - DCHECK_EQ(rl_dest.fp, loc.fp); - DCHECK_EQ(rl_dest.core, loc.core); - DCHECK_EQ(rl_dest.ref, loc.ref); - SafeMap<unsigned int, unsigned int>::iterator it; - it = mir_graph_->block_id_map_.find(incoming[i]); - DCHECK(it != mir_graph_->block_id_map_.end()); - DCHECK(GetLLVMValue(loc.orig_sreg) != NULL); - DCHECK(GetLLVMBlock(it->second) != NULL); - phi->addIncoming(GetLLVMValue(loc.orig_sreg), - GetLLVMBlock(it->second)); - } - DefineValueOnly(phi, rl_dest.orig_sreg); - } -} - -/* Extended MIR instructions like PHI */ -void MirConverter::ConvertExtendedMIR(BasicBlock* bb, MIR* mir, - ::llvm::BasicBlock* llvm_bb) { - switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) { - case kMirOpPhi: { - // The llvm Phi node already emitted - just DefineValue() here. - RegLocation rl_dest = mir_graph_->reg_location_[mir->ssa_rep->defs[0]]; - if (!rl_dest.high_word) { - // Only consider low word of pairs. - DCHECK(GetLLVMValue(rl_dest.orig_sreg) != NULL); - ::llvm::Value* phi = GetLLVMValue(rl_dest.orig_sreg); - if (1) SetVregOnValue(phi, rl_dest.orig_sreg); - } - break; - } - case kMirOpCopy: { - UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi"; - break; - } - case kMirOpNop: - if ((mir == bb->last_mir_insn) && (bb->taken == NullBasicBlockId) && - (bb->fall_through == NullBasicBlockId)) { - irb_->CreateUnreachable(); - } - break; - - // TODO: need GBC intrinsic to take advantage of fused operations - case kMirOpFusedCmplFloat: - UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported"; - break; - case kMirOpFusedCmpgFloat: - UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported"; - break; - case kMirOpFusedCmplDouble: - UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported"; - break; - case kMirOpFusedCmpgDouble: - UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported"; - break; - case kMirOpFusedCmpLong: - UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported"; - break; - default: - break; - } -} - -/* Handle the content in each basic block */ -bool MirConverter::BlockBitcodeConversion(BasicBlock* bb) { - if (bb->block_type == kDead) return false; - ::llvm::BasicBlock* llvm_bb = GetLLVMBlock(bb->id); - if (llvm_bb == NULL) { - CHECK(bb->block_type == kExitBlock); - } else { - irb_->SetInsertPoint(llvm_bb); - SetDexOffset(bb->start_offset); - } - - if (cu_->verbose) { - LOG(INFO) << "................................"; - LOG(INFO) << "Block id " << bb->id; - if (llvm_bb != NULL) { - LOG(INFO) << "label " << llvm_bb->getName().str().c_str(); - } else { - LOG(INFO) << "llvm_bb is NULL"; - } - } - - if (bb->block_type == kEntryBlock) { - SetMethodInfo(); - - { // Allocate shadowframe. - art::llvm::IntrinsicHelper::IntrinsicId id = - art::llvm::IntrinsicHelper::AllocaShadowFrame; - ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(id); - ::llvm::Value* entries = irb_->getInt32(mir_graph_->GetNumOfCodeVRs()); - irb_->CreateCall(func, entries); - } - - { // Store arguments to vregs. - uint16_t arg_reg = mir_graph_->GetFirstInVR(); - - ::llvm::Function::arg_iterator arg_iter(func_->arg_begin()); - - const char* shorty = cu_->shorty; - uint32_t shorty_size = strlen(shorty); - CHECK_GE(shorty_size, 1u); - - ++arg_iter; // skip method object - - if ((cu_->access_flags & kAccStatic) == 0) { - SetVregOnValue(arg_iter, arg_reg); - ++arg_iter; - ++arg_reg; - } - - for (uint32_t i = 1; i < shorty_size; ++i, ++arg_iter) { - SetVregOnValue(arg_iter, arg_reg); - - ++arg_reg; - if (shorty[i] == 'J' || shorty[i] == 'D') { - // Wide types, such as long and double, are using a pair of registers - // to store the value, so we have to increase arg_reg again. - ++arg_reg; - } - } - } - } else if (bb->block_type == kExitBlock) { - /* - * Because of the differences between how MIR/LIR and llvm handle exit - * blocks, we won't explicitly covert them. On the llvm-to-lir - * path, it will need to be regenereated. - */ - return false; - } else if (bb->block_type == kExceptionHandling) { - /* - * Because we're deferring null checking, delete the associated empty - * exception block. - */ - llvm_bb->eraseFromParent(); - return false; - } - - HandlePhiNodes(bb, llvm_bb); - - for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) { - SetDexOffset(mir->offset); - - int opcode = mir->dalvikInsn.opcode; - Instruction::Format dalvik_format = - Instruction::FormatOf(mir->dalvikInsn.opcode); - - if (opcode == kMirOpCheck) { - // Combine check and work halves of throwing instruction. - MIR* work_half = mir->meta.throw_insn; - mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode; - opcode = mir->dalvikInsn.opcode; - SSARepresentation* ssa_rep = work_half->ssa_rep; - work_half->ssa_rep = mir->ssa_rep; - mir->ssa_rep = ssa_rep; - work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop); - if (bb->successor_block_list_type == kCatch) { - ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction( - art::llvm::IntrinsicHelper::CatchTargets); - ::llvm::Value* switch_key = - irb_->CreateCall(intr, irb_->getInt32(mir->offset)); - // New basic block to use for work half - ::llvm::BasicBlock* work_bb = - ::llvm::BasicBlock::Create(*context_, "", func_); - ::llvm::SwitchInst* sw = - irb_->CreateSwitch(switch_key, work_bb, bb->successor_blocks.size()); - for (SuccessorBlockInfo *successor_block_info : bb->successor_blocks) { - ::llvm::BasicBlock *target = - GetLLVMBlock(successor_block_info->block); - int type_index = successor_block_info->key; - sw->addCase(irb_->getInt32(type_index), target); - } - llvm_bb = work_bb; - irb_->SetInsertPoint(llvm_bb); - } - } - - if (IsPseudoMirOp(opcode)) { - ConvertExtendedMIR(bb, mir, llvm_bb); - continue; - } - - bool not_handled = ConvertMIRNode(mir, bb, llvm_bb); - if (not_handled) { - Instruction::Code dalvik_opcode = static_cast<Instruction::Code>(opcode); - LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled", - mir->offset, opcode, - Instruction::Name(dalvik_opcode), - dalvik_format); - } - } - - if (bb->block_type == kEntryBlock) { - entry_target_bb_ = GetLLVMBlock(bb->fall_through); - } else if ((bb->fall_through != NullBasicBlockId) && !bb->terminated_by_return) { - irb_->CreateBr(GetLLVMBlock(bb->fall_through)); - } - - return false; -} - -char RemapShorty(char shorty_type) { - /* - * TODO: might want to revisit this. Dalvik registers are 32-bits wide, - * and longs/doubles are represented as a pair of registers. When sub-word - * arguments (and method results) are passed, they are extended to Dalvik - * virtual register containers. Because llvm is picky about type consistency, - * we must either cast the "real" type to 32-bit container multiple Dalvik - * register types, or always use the expanded values. - * Here, we're doing the latter. We map the shorty signature to container - * types (which is valid so long as we always do a real expansion of passed - * arguments and field loads). - */ - switch (shorty_type) { - case 'Z' : shorty_type = 'I'; break; - case 'B' : shorty_type = 'I'; break; - case 'S' : shorty_type = 'I'; break; - case 'C' : shorty_type = 'I'; break; - default: break; - } - return shorty_type; -} - -::llvm::FunctionType* MirConverter::GetFunctionType() { - // Get return type - ::llvm::Type* ret_type = irb_->getJType(RemapShorty(cu_->shorty[0])); - - // Get argument type - std::vector< ::llvm::Type*> args_type; - - // method object - args_type.push_back(irb_->getJMethodTy()); - - // Do we have a "this"? - if ((cu_->access_flags & kAccStatic) == 0) { - args_type.push_back(irb_->getJObjectTy()); - } - - for (uint32_t i = 1; i < strlen(cu_->shorty); ++i) { - args_type.push_back(irb_->getJType(RemapShorty(cu_->shorty[i]))); - } - - return ::llvm::FunctionType::get(ret_type, args_type, false); -} - -bool MirConverter::CreateFunction() { - ::llvm::FunctionType* func_type = GetFunctionType(); - if (func_type == NULL) { - return false; - } - - func_ = ::llvm::Function::Create(func_type, - ::llvm::Function::InternalLinkage, - symbol_, module_); - - ::llvm::Function::arg_iterator arg_iter(func_->arg_begin()); - ::llvm::Function::arg_iterator arg_end(func_->arg_end()); - - arg_iter->setName("method"); - ++arg_iter; - - int start_sreg = mir_graph_->GetFirstInVR(); - - for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) { - arg_iter->setName(StringPrintf("v%i_0", start_sreg)); - start_sreg += mir_graph_->reg_location_[start_sreg].wide ? 2 : 1; - } - - return true; -} - -bool MirConverter::CreateLLVMBasicBlock(BasicBlock* bb) { - // Skip the exit block - if ((bb->block_type == kDead) ||(bb->block_type == kExitBlock)) { - id_to_block_map_.Put(bb->id, NULL); - } else { - int offset = bb->start_offset; - bool entry_block = (bb->block_type == kEntryBlock); - ::llvm::BasicBlock* llvm_bb = - ::llvm::BasicBlock::Create(*context_, entry_block ? "entry" : - StringPrintf(kLabelFormat, bb->catch_entry ? kCatchBlock : - kNormalBlock, offset, bb->id), func_); - if (entry_block) { - entry_bb_ = llvm_bb; - placeholder_bb_ = - ::llvm::BasicBlock::Create(*context_, "placeholder", - func_); - } - id_to_block_map_.Put(bb->id, llvm_bb); - } - return false; -} - - -/* - * Convert MIR to LLVM_IR - * o For each ssa name, create LLVM named value. Type these - * appropriately, and ignore high half of wide and double operands. - * o For each MIR basic block, create an LLVM basic block. - * o Iterate through the MIR a basic block at a time, setting arguments - * to recovered ssa name. - */ -void MirConverter::MethodMIR2Bitcode() { - InitIR(); - - // Create the function - CreateFunction(); - - // Create an LLVM basic block for each MIR block in dfs preorder - PreOrderDfsIterator iter(mir_graph_); - for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { - CreateLLVMBasicBlock(bb); - } - - /* - * Create an llvm named value for each MIR SSA name. Note: we'll use - * placeholders for all non-argument values (because we haven't seen - * the definition yet). - */ - irb_->SetInsertPoint(placeholder_bb_); - ::llvm::Function::arg_iterator arg_iter(func_->arg_begin()); - arg_iter++; /* Skip path method */ - for (int i = 0; i < mir_graph_->GetNumSSARegs(); i++) { - ::llvm::Value* val; - RegLocation rl_temp = mir_graph_->reg_location_[i]; - if ((mir_graph_->SRegToVReg(i) < 0) || rl_temp.high_word) { - llvm_values_.push_back(0); - } else if ((i < mir_graph_->GetFirstInVR()) || - (i >= (mir_graph_->GetFirstTempVR()))) { - ::llvm::Constant* imm_value = mir_graph_->reg_location_[i].wide ? - irb_->getJLong(0) : irb_->getJInt(0); - val = EmitConst(imm_value, mir_graph_->reg_location_[i]); - val->setName(mir_graph_->GetSSAName(i)); - llvm_values_.push_back(val); - } else { - // Recover previously-created argument values - ::llvm::Value* arg_val = arg_iter++; - llvm_values_.push_back(arg_val); - } - } - - PreOrderDfsIterator iter2(mir_graph_); - for (BasicBlock* bb = iter2.Next(); bb != NULL; bb = iter2.Next()) { - BlockBitcodeConversion(bb); - } - - /* - * In a few rare cases of verification failure, the verifier will - * replace one or more Dalvik opcodes with the special - * throw-verification-failure opcode. This can leave the SSA graph - * in an invalid state, as definitions may be lost, while uses retained. - * To work around this problem, we insert placeholder definitions for - * all Dalvik SSA regs in the "placeholder" block. Here, after - * bitcode conversion is complete, we examine those placeholder definitions - * and delete any with no references (which normally is all of them). - * - * If any definitions remain, we link the placeholder block into the - * CFG. Otherwise, it is deleted. - */ - for (::llvm::BasicBlock::iterator it = placeholder_bb_->begin(), - it_end = placeholder_bb_->end(); it != it_end;) { - ::llvm::Instruction* inst = ::llvm::dyn_cast< ::llvm::Instruction>(it++); - DCHECK(inst != NULL); - ::llvm::Value* val = ::llvm::dyn_cast< ::llvm::Value>(inst); - DCHECK(val != NULL); - if (val->getNumUses() == 0) { - inst->eraseFromParent(); - } - } - SetDexOffset(0); - if (placeholder_bb_->empty()) { - placeholder_bb_->eraseFromParent(); - } else { - irb_->SetInsertPoint(placeholder_bb_); - irb_->CreateBr(entry_target_bb_); - entry_target_bb_ = placeholder_bb_; - } - irb_->SetInsertPoint(entry_bb_); - irb_->CreateBr(entry_target_bb_); - - if (cu_->enable_debug & (1 << kDebugVerifyBitcode)) { - if (::llvm::verifyFunction(*func_, ::llvm::PrintMessageAction)) { - LOG(INFO) << "Bitcode verification FAILED for " - << PrettyMethod(cu_->method_idx, *cu_->dex_file) - << " of size " << mir_graph_->GetNumDalvikInsns(); - cu_->enable_debug |= (1 << kDebugDumpBitcodeFile); - } - } - - if (cu_->enable_debug & (1 << kDebugDumpBitcodeFile)) { - // Write bitcode to file - std::string errmsg; - std::string fname(PrettyMethod(cu_->method_idx, *cu_->dex_file)); - mir_graph_->ReplaceSpecialChars(fname); - // TODO: make configurable change naming mechanism to avoid fname length issues. - fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str()); - - if (fname.size() > 240) { - LOG(INFO) << "Warning: bitcode filename too long. Truncated."; - fname.resize(240); - } - - ::llvm::OwningPtr< ::llvm::tool_output_file> out_file( - new ::llvm::tool_output_file(fname.c_str(), errmsg, - ::llvm::sys::fs::F_Binary)); - - if (!errmsg.empty()) { - LOG(ERROR) << "Failed to create bitcode output file: " << errmsg; - } - - ::llvm::WriteBitcodeToFile(module_, out_file->os()); - out_file->keep(); - } -} - -Backend* PortableCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph, - ArenaAllocator* const arena, - llvm::LlvmCompilationUnit* const llvm_compilation_unit) { - return new MirConverter(cu, mir_graph, arena, llvm_compilation_unit); -} - -} // namespace art diff --git a/compiler/dex/portable/mir_to_gbc.h b/compiler/dex/portable/mir_to_gbc.h deleted file mode 100644 index bc4f5c4100..0000000000 --- a/compiler/dex/portable/mir_to_gbc.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_ -#define ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_ - -#include <llvm/ADT/ArrayRef.h> -#include <llvm/IR/BasicBlock.h> -#include <llvm/IR/IRBuilder.h> -#include <llvm/IR/LLVMContext.h> -#include <llvm/IR/Module.h> - -#include "invoke_type.h" -#include "compiled_method.h" -#include "dex/compiler_enums.h" -#include "dex/compiler_ir.h" -#include "dex/backend.h" -#include "llvm/intrinsic_helper.h" -#include "llvm/llvm_compilation_unit.h" -#include "safe_map.h" -#include "utils/arena_containers.h" - -namespace llvm { - class Module; - class LLVMContext; -} - -namespace art { - -namespace llvm { - class IntrinsicHelper; - class IRBuilder; -} - -class LLVMInfo { - public: - LLVMInfo(); - ~LLVMInfo(); - - ::llvm::LLVMContext* GetLLVMContext() { - return llvm_context_.get(); - } - - ::llvm::Module* GetLLVMModule() { - return llvm_module_; - } - - art::llvm::IntrinsicHelper* GetIntrinsicHelper() { - return intrinsic_helper_.get(); - } - - art::llvm::IRBuilder* GetIRBuilder() { - return ir_builder_.get(); - } - - private: - std::unique_ptr< ::llvm::LLVMContext> llvm_context_; - ::llvm::Module* llvm_module_; // Managed by context_. - std::unique_ptr<art::llvm::IntrinsicHelper> intrinsic_helper_; - std::unique_ptr<art::llvm::IRBuilder> ir_builder_; -}; - -class BasicBlock; -struct CallInfo; -struct CompilationUnit; -struct MIR; -struct RegLocation; -struct RegisterInfo; -class MIRGraph; - -// Target-specific initialization. -Backend* PortableCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph, - ArenaAllocator* const arena, - llvm::LlvmCompilationUnit* const llvm_compilation_unit); - -class MirConverter : public Backend { - public: - // TODO: flesh out and integrate into new world order. - MirConverter(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena, - llvm::LlvmCompilationUnit* llvm_compilation_unit) - : Backend(arena), - cu_(cu), - mir_graph_(mir_graph), - llvm_compilation_unit_(llvm_compilation_unit), - llvm_info_(llvm_compilation_unit->GetQuickContext()), - symbol_(llvm_compilation_unit->GetDexCompilationUnit()->GetSymbol()), - context_(NULL), - module_(NULL), - func_(NULL), - intrinsic_helper_(NULL), - irb_(NULL), - placeholder_bb_(NULL), - entry_bb_(NULL), - entry_target_bb_(NULL), - llvm_values_(arena->Adapter()), - temp_name_(0), - current_dalvik_offset_(0) { - llvm_values_.reserve(mir_graph->GetNumSSARegs()); - if (kIsDebugBuild) { - cu->enable_debug |= (1 << kDebugVerifyBitcode); - } - } - - void Materialize() { - MethodMIR2Bitcode(); - } - - CompiledMethod* GetCompiledMethod() { - return NULL; - } - - private: - ::llvm::BasicBlock* GetLLVMBlock(int id); - ::llvm::Value* GetLLVMValue(int s_reg); - void SetVregOnValue(::llvm::Value* val, int s_reg); - void DefineValueOnly(::llvm::Value* val, int s_reg); - void DefineValue(::llvm::Value* val, int s_reg); - ::llvm::Type* LlvmTypeFromLocRec(RegLocation loc); - void InitIR(); - ::llvm::BasicBlock* FindCaseTarget(uint32_t vaddr); - void ConvertPackedSwitch(BasicBlock* bb, MIR* mir, int32_t table_offset, - RegLocation rl_src); - void ConvertSparseSwitch(BasicBlock* bb, MIR* mir, int32_t table_offset, - RegLocation rl_src); - void ConvertSget(int32_t field_index, - art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest); - void ConvertSput(int32_t field_index, - art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src); - void ConvertFillArrayData(int32_t offset, RegLocation rl_array); - ::llvm::Value* EmitConst(::llvm::ArrayRef< ::llvm::Value*> src, - RegLocation loc); - void EmitPopShadowFrame(); - ::llvm::Value* EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src, - RegLocation loc); - void ConvertMoveException(RegLocation rl_dest); - void ConvertThrow(RegLocation rl_src); - void ConvertMonitorEnterExit(int opt_flags, - art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src); - void ConvertArrayLength(int opt_flags, RegLocation rl_dest, - RegLocation rl_src); - void EmitSuspendCheck(); - ::llvm::Value* ConvertCompare(ConditionCode cc, - ::llvm::Value* src1, ::llvm::Value* src2); - void ConvertCompareAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc, - RegLocation rl_src1, RegLocation rl_src2); - void ConvertCompareZeroAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc, - RegLocation rl_src1); - ::llvm::Value* GenDivModOp(bool is_div, bool is_long, ::llvm::Value* src1, - ::llvm::Value* src2); - ::llvm::Value* GenArithOp(OpKind op, bool is_long, ::llvm::Value* src1, - ::llvm::Value* src2); - void ConvertFPArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2); - void ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - void ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_src, int shift_amount); - void ConvertArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2); - void ConvertArithOpLit(OpKind op, RegLocation rl_dest, RegLocation rl_src1, - int32_t imm); - void ConvertInvoke(BasicBlock* bb, MIR* mir, InvokeType invoke_type, - bool is_range, bool is_filled_new_array); - void ConvertConstObject(uint32_t idx, - art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest); - void ConvertCheckCast(uint32_t type_idx, RegLocation rl_src); - void ConvertNewInstance(uint32_t type_idx, RegLocation rl_dest); - void ConvertNewArray(uint32_t type_idx, RegLocation rl_dest, - RegLocation rl_src); - void ConvertAget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index); - void ConvertAput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_src, RegLocation rl_array, RegLocation rl_index); - void ConvertIget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_obj, int field_index); - void ConvertIput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_src, RegLocation rl_obj, int field_index); - void ConvertInstanceOf(uint32_t type_idx, RegLocation rl_dest, - RegLocation rl_src); - void ConvertIntToLong(RegLocation rl_dest, RegLocation rl_src); - void ConvertLongToInt(RegLocation rl_dest, RegLocation rl_src); - void ConvertFloatToDouble(RegLocation rl_dest, RegLocation rl_src); - void ConvertDoubleToFloat(RegLocation rl_dest, RegLocation rl_src); - void ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - void ConvertIntNarrowing(RegLocation rl_dest, RegLocation rl_src, - art::llvm::IntrinsicHelper::IntrinsicId id); - void ConvertNeg(RegLocation rl_dest, RegLocation rl_src); - void ConvertIntToFP(::llvm::Type* ty, RegLocation rl_dest, RegLocation rl_src); - void ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id, - RegLocation rl_dest, RegLocation rl_src); - void ConvertNegFP(RegLocation rl_dest, RegLocation rl_src); - void ConvertNot(RegLocation rl_dest, RegLocation rl_src); - void EmitConstructorBarrier(); - bool ConvertMIRNode(MIR* mir, BasicBlock* bb, ::llvm::BasicBlock* llvm_bb); - void SetDexOffset(int32_t offset); - void SetMethodInfo(); - void HandlePhiNodes(BasicBlock* bb, ::llvm::BasicBlock* llvm_bb); - void ConvertExtendedMIR(BasicBlock* bb, MIR* mir, ::llvm::BasicBlock* llvm_bb); - bool BlockBitcodeConversion(BasicBlock* bb); - ::llvm::FunctionType* GetFunctionType(); - bool CreateFunction(); - bool CreateLLVMBasicBlock(BasicBlock* bb); - void MethodMIR2Bitcode(); - - CompilationUnit* cu_; - MIRGraph* mir_graph_; - llvm::LlvmCompilationUnit* const llvm_compilation_unit_; - LLVMInfo* llvm_info_; - std::string symbol_; - ::llvm::LLVMContext* context_; - ::llvm::Module* module_; - ::llvm::Function* func_; - art::llvm::IntrinsicHelper* intrinsic_helper_; - art::llvm::IRBuilder* irb_; - ::llvm::BasicBlock* placeholder_bb_; - ::llvm::BasicBlock* entry_bb_; - ::llvm::BasicBlock* entry_target_bb_; - std::string bitcode_filename_; - ArenaVector< ::llvm::Value*> llvm_values_; - int32_t temp_name_; - SafeMap<int32_t, ::llvm::BasicBlock*> id_to_block_map_; // block id -> llvm bb. - int current_dalvik_offset_; -}; // Class MirConverter - -} // namespace art - -#endif // ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_ diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc index fb098c3975..c14e22e090 100644 --- a/compiler/dex/quick/quick_compiler.cc +++ b/compiler/dex/quick/quick_compiler.cc @@ -19,6 +19,7 @@ #include <cstdint> #include "compiler.h" +#include "dex_file-inl.h" #include "dex/frontend.h" #include "dex/mir_graph.h" #include "dex/quick/mir_to_lir.h" @@ -588,17 +589,6 @@ CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item, uint32_t method_idx, jobject class_loader, const DexFile& dex_file) const { - CompiledMethod* method = TryCompileWithSeaIR(code_item, - access_flags, - invoke_type, - class_def_idx, - method_idx, - class_loader, - dex_file); - if (method != nullptr) { - return method; - } - // TODO: check method fingerprint here to determine appropriate backend type. Until then, use // build default. CompilerDriver* driver = GetCompilerDriver(); diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc index 932a532e56..60d24068b1 100644 --- a/compiler/dex/verification_results.cc +++ b/compiler/dex/verification_results.cc @@ -106,18 +106,8 @@ bool VerificationResults::IsClassRejected(ClassReference ref) { return (rejected_classes_.find(ref) != rejected_classes_.end()); } -bool VerificationResults::IsCandidateForCompilation(MethodReference& method_ref, +bool VerificationResults::IsCandidateForCompilation(MethodReference&, const uint32_t access_flags) { -#ifdef ART_SEA_IR_MODE - bool use_sea = compiler_options_->GetSeaIrMode(); - use_sea = use_sea && (std::string::npos != PrettyMethod( - method_ref.dex_method_index, *(method_ref.dex_file)).find("fibonacci")); - if (use_sea) { - return true; - } -#else - UNUSED(method_ref); -#endif if (!compiler_options_->IsCompilationEnabled()) { return false; } |