summaryrefslogtreecommitdiffstats
path: root/compiler/dex
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/dex')
-rw-r--r--compiler/dex/frontend.cc2
-rw-r--r--compiler/dex/frontend.h2
-rw-r--r--compiler/dex/mir_optimization.cc3
-rw-r--r--compiler/dex/portable/mir_to_gbc.cc2003
-rw-r--r--compiler/dex/portable/mir_to_gbc.h241
-rw-r--r--compiler/dex/quick/quick_compiler.cc12
-rw-r--r--compiler/dex/verification_results.cc12
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;
}