blob: fd67608e736a53fa7f2807e96d422f3ec82f4f45 [file] [log] [blame]
Brian Carlstrom7940e442013-07-12 13:46:57 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "object_utils.h"
18
19#include <llvm/ADT/DepthFirstIterator.h>
20#include <llvm/Analysis/Verifier.h>
21#include <llvm/Bitcode/ReaderWriter.h>
22#include <llvm/IR/Instruction.h>
23#include <llvm/IR/Instructions.h>
24#include <llvm/IR/Metadata.h>
25#include <llvm/IR/Type.h>
26#include <llvm/Support/Casting.h>
27#include <llvm/Support/InstIterator.h>
28#include <llvm/Support/ToolOutputFile.h>
29
30#include "dex/compiler_internals.h"
31#include "dex/dataflow_iterator-inl.h"
32#include "dex/frontend.h"
Ian Rogersb48b9eb2014-02-28 16:20:21 -080033#include "llvm/ir_builder.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070034#include "llvm/llvm_compilation_unit.h"
35#include "llvm/utils_llvm.h"
Ian Rogers02ed4c02013-09-06 13:10:04 -070036#include "mir_to_gbc.h"
37#include "thread-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070038
39const char* kLabelFormat = "%c0x%x_%d";
40const char kInvalidBlock = 0xff;
41const char kNormalBlock = 'L';
42const char kCatchBlock = 'C';
43
44namespace art {
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +000045namespace llvm {
46::llvm::Module* makeLLVMModuleContents(::llvm::Module* module);
47}
48
49LLVMInfo::LLVMInfo() {
50 // Create context, module, intrinsic helper & ir builder
51 llvm_context_.reset(new ::llvm::LLVMContext());
52 llvm_module_ = new ::llvm::Module("art", *llvm_context_);
53 ::llvm::StructType::create(*llvm_context_, "JavaObject");
54 art::llvm::makeLLVMModuleContents(llvm_module_);
55 intrinsic_helper_.reset(new art::llvm::IntrinsicHelper(*llvm_context_, *llvm_module_));
56 ir_builder_.reset(new art::llvm::IRBuilder(*llvm_context_, *llvm_module_, *intrinsic_helper_));
57}
58
59LLVMInfo::~LLVMInfo() {
60}
Brian Carlstrom7940e442013-07-12 13:46:57 -070061
Brian Carlstrom2ce745c2013-07-17 17:44:30 -070062::llvm::BasicBlock* MirConverter::GetLLVMBlock(int id) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070063 return id_to_block_map_.Get(id);
64}
65
Brian Carlstrom2ce745c2013-07-17 17:44:30 -070066::llvm::Value* MirConverter::GetLLVMValue(int s_reg) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070067 return llvm_values_.Get(s_reg);
68}
69
Brian Carlstrom2ce745c2013-07-17 17:44:30 -070070void MirConverter::SetVregOnValue(::llvm::Value* val, int s_reg) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070071 // Set vreg for debugging
72 art::llvm::IntrinsicHelper::IntrinsicId id = art::llvm::IntrinsicHelper::SetVReg;
73 ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(id);
74 int v_reg = mir_graph_->SRegToVReg(s_reg);
75 ::llvm::Value* table_slot = irb_->getInt32(v_reg);
76 ::llvm::Value* args[] = { table_slot, val };
77 irb_->CreateCall(func, args);
78}
79
80// Replace the placeholder value with the real definition
Brian Carlstrom2ce745c2013-07-17 17:44:30 -070081void MirConverter::DefineValueOnly(::llvm::Value* val, int s_reg) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070082 ::llvm::Value* placeholder = GetLLVMValue(s_reg);
83 if (placeholder == NULL) {
84 // This can happen on instruction rewrite on verification failure
85 LOG(WARNING) << "Null placeholder";
86 return;
87 }
88 placeholder->replaceAllUsesWith(val);
89 val->takeName(placeholder);
90 llvm_values_.Put(s_reg, val);
91 ::llvm::Instruction* inst = ::llvm::dyn_cast< ::llvm::Instruction>(placeholder);
92 DCHECK(inst != NULL);
93 inst->eraseFromParent();
Brian Carlstrom7940e442013-07-12 13:46:57 -070094}
95
Brian Carlstrom2ce745c2013-07-17 17:44:30 -070096void MirConverter::DefineValue(::llvm::Value* val, int s_reg) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070097 DefineValueOnly(val, s_reg);
98 SetVregOnValue(val, s_reg);
99}
100
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700101::llvm::Type* MirConverter::LlvmTypeFromLocRec(RegLocation loc) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700102 ::llvm::Type* res = NULL;
103 if (loc.wide) {
104 if (loc.fp)
105 res = irb_->getDoubleTy();
106 else
107 res = irb_->getInt64Ty();
108 } else {
109 if (loc.fp) {
110 res = irb_->getFloatTy();
111 } else {
112 if (loc.ref)
113 res = irb_->getJObjectTy();
114 else
115 res = irb_->getInt32Ty();
116 }
117 }
118 return res;
119}
120
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700121void MirConverter::InitIR() {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700122 if (llvm_info_ == NULL) {
123 CompilerTls* tls = cu_->compiler_driver->GetTls();
124 CHECK(tls != NULL);
125 llvm_info_ = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
126 if (llvm_info_ == NULL) {
127 llvm_info_ = new LLVMInfo();
128 tls->SetLLVMInfo(llvm_info_);
129 }
130 }
131 context_ = llvm_info_->GetLLVMContext();
132 module_ = llvm_info_->GetLLVMModule();
133 intrinsic_helper_ = llvm_info_->GetIntrinsicHelper();
134 irb_ = llvm_info_->GetIRBuilder();
135}
136
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700137::llvm::BasicBlock* MirConverter::FindCaseTarget(uint32_t vaddr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700138 BasicBlock* bb = mir_graph_->FindBlock(vaddr);
139 DCHECK(bb != NULL);
140 return GetLLVMBlock(bb->id);
141}
142
143void MirConverter::ConvertPackedSwitch(BasicBlock* bb,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700144 int32_t table_offset, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700145 const Instruction::PackedSwitchPayload* payload =
146 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
147 cu_->insns + current_dalvik_offset_ + table_offset);
148
149 ::llvm::Value* value = GetLLVMValue(rl_src.orig_sreg);
150
151 ::llvm::SwitchInst* sw =
buzbee0d829482013-10-11 15:24:55 -0700152 irb_->CreateSwitch(value, GetLLVMBlock(bb->fall_through),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700153 payload->case_count);
154
155 for (uint16_t i = 0; i < payload->case_count; ++i) {
156 ::llvm::BasicBlock* llvm_bb =
157 FindCaseTarget(current_dalvik_offset_ + payload->targets[i]);
158 sw->addCase(irb_->getInt32(payload->first_key + i), llvm_bb);
159 }
160 ::llvm::MDNode* switch_node =
161 ::llvm::MDNode::get(*context_, irb_->getInt32(table_offset));
162 sw->setMetadata("SwitchTable", switch_node);
buzbee0d829482013-10-11 15:24:55 -0700163 bb->taken = NullBasicBlockId;
164 bb->fall_through = NullBasicBlockId;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700165}
166
167void MirConverter::ConvertSparseSwitch(BasicBlock* bb,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700168 int32_t table_offset, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700169 const Instruction::SparseSwitchPayload* payload =
170 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
171 cu_->insns + current_dalvik_offset_ + table_offset);
172
173 const int32_t* keys = payload->GetKeys();
174 const int32_t* targets = payload->GetTargets();
175
176 ::llvm::Value* value = GetLLVMValue(rl_src.orig_sreg);
177
178 ::llvm::SwitchInst* sw =
buzbee0d829482013-10-11 15:24:55 -0700179 irb_->CreateSwitch(value, GetLLVMBlock(bb->fall_through),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700180 payload->case_count);
181
182 for (size_t i = 0; i < payload->case_count; ++i) {
183 ::llvm::BasicBlock* llvm_bb =
184 FindCaseTarget(current_dalvik_offset_ + targets[i]);
185 sw->addCase(irb_->getInt32(keys[i]), llvm_bb);
186 }
187 ::llvm::MDNode* switch_node =
188 ::llvm::MDNode::get(*context_, irb_->getInt32(table_offset));
189 sw->setMetadata("SwitchTable", switch_node);
buzbee0d829482013-10-11 15:24:55 -0700190 bb->taken = NullBasicBlockId;
191 bb->fall_through = NullBasicBlockId;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700192}
193
194void MirConverter::ConvertSget(int32_t field_index,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700195 art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700196 ::llvm::Constant* field_idx = irb_->getInt32(field_index);
197 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
198 ::llvm::Value* res = irb_->CreateCall(intr, field_idx);
199 DefineValue(res, rl_dest.orig_sreg);
200}
201
202void MirConverter::ConvertSput(int32_t field_index,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700203 art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700204 ::llvm::SmallVector< ::llvm::Value*, 2> args;
205 args.push_back(irb_->getInt32(field_index));
206 args.push_back(GetLLVMValue(rl_src.orig_sreg));
207 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
208 irb_->CreateCall(intr, args);
209}
210
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700211void MirConverter::ConvertFillArrayData(int32_t offset, RegLocation rl_array) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700212 art::llvm::IntrinsicHelper::IntrinsicId id;
213 id = art::llvm::IntrinsicHelper::HLFillArrayData;
214 ::llvm::SmallVector< ::llvm::Value*, 2> args;
215 args.push_back(irb_->getInt32(offset));
216 args.push_back(GetLLVMValue(rl_array.orig_sreg));
217 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
218 irb_->CreateCall(intr, args);
219}
220
221::llvm::Value* MirConverter::EmitConst(::llvm::ArrayRef< ::llvm::Value*> src,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700222 RegLocation loc) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700223 art::llvm::IntrinsicHelper::IntrinsicId id;
224 if (loc.wide) {
225 if (loc.fp) {
226 id = art::llvm::IntrinsicHelper::ConstDouble;
227 } else {
228 id = art::llvm::IntrinsicHelper::ConstLong;
229 }
230 } else {
231 if (loc.fp) {
232 id = art::llvm::IntrinsicHelper::ConstFloat;
233 } else if (loc.ref) {
234 id = art::llvm::IntrinsicHelper::ConstObj;
235 } else {
236 id = art::llvm::IntrinsicHelper::ConstInt;
237 }
238 }
239 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
240 return irb_->CreateCall(intr, src);
241}
242
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700243void MirConverter::EmitPopShadowFrame() {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700244 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(
245 art::llvm::IntrinsicHelper::PopShadowFrame);
246 irb_->CreateCall(intr);
247}
248
249::llvm::Value* MirConverter::EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700250 RegLocation loc) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700251 art::llvm::IntrinsicHelper::IntrinsicId id;
252 if (loc.wide) {
253 if (loc.fp) {
254 id = art::llvm::IntrinsicHelper::CopyDouble;
255 } else {
256 id = art::llvm::IntrinsicHelper::CopyLong;
257 }
258 } else {
259 if (loc.fp) {
260 id = art::llvm::IntrinsicHelper::CopyFloat;
261 } else if (loc.ref) {
262 id = art::llvm::IntrinsicHelper::CopyObj;
263 } else {
264 id = art::llvm::IntrinsicHelper::CopyInt;
265 }
266 }
267 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
268 return irb_->CreateCall(intr, src);
269}
270
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700271void MirConverter::ConvertMoveException(RegLocation rl_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700272 ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(
273 art::llvm::IntrinsicHelper::GetException);
274 ::llvm::Value* res = irb_->CreateCall(func);
275 DefineValue(res, rl_dest.orig_sreg);
276}
277
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700278void MirConverter::ConvertThrow(RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700279 ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg);
280 ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(
281 art::llvm::IntrinsicHelper::HLThrowException);
282 irb_->CreateCall(func, src);
283}
284
285void MirConverter::ConvertMonitorEnterExit(int opt_flags,
286 art::llvm::IntrinsicHelper::IntrinsicId id,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700287 RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700288 ::llvm::SmallVector< ::llvm::Value*, 2> args;
289 args.push_back(irb_->getInt32(opt_flags));
290 args.push_back(GetLLVMValue(rl_src.orig_sreg));
291 ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(id);
292 irb_->CreateCall(func, args);
293}
294
295void MirConverter::ConvertArrayLength(int opt_flags,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700296 RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700297 ::llvm::SmallVector< ::llvm::Value*, 2> args;
298 args.push_back(irb_->getInt32(opt_flags));
299 args.push_back(GetLLVMValue(rl_src.orig_sreg));
300 ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(
301 art::llvm::IntrinsicHelper::OptArrayLength);
302 ::llvm::Value* res = irb_->CreateCall(func, args);
303 DefineValue(res, rl_dest.orig_sreg);
304}
305
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700306void MirConverter::EmitSuspendCheck() {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700307 art::llvm::IntrinsicHelper::IntrinsicId id =
308 art::llvm::IntrinsicHelper::CheckSuspend;
309 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
310 irb_->CreateCall(intr);
311}
312
313::llvm::Value* MirConverter::ConvertCompare(ConditionCode cc,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700314 ::llvm::Value* src1, ::llvm::Value* src2) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700315 ::llvm::Value* res = NULL;
316 DCHECK_EQ(src1->getType(), src2->getType());
Brian Carlstromdf629502013-07-17 22:39:56 -0700317 switch (cc) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700318 case kCondEq: res = irb_->CreateICmpEQ(src1, src2); break;
319 case kCondNe: res = irb_->CreateICmpNE(src1, src2); break;
320 case kCondLt: res = irb_->CreateICmpSLT(src1, src2); break;
321 case kCondGe: res = irb_->CreateICmpSGE(src1, src2); break;
322 case kCondGt: res = irb_->CreateICmpSGT(src1, src2); break;
323 case kCondLe: res = irb_->CreateICmpSLE(src1, src2); break;
324 default: LOG(FATAL) << "Unexpected cc value " << cc;
325 }
326 return res;
327}
328
329void MirConverter::ConvertCompareAndBranch(BasicBlock* bb, MIR* mir,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700330 ConditionCode cc, RegLocation rl_src1, RegLocation rl_src2) {
buzbee0d829482013-10-11 15:24:55 -0700331 if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= mir->offset) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700332 EmitSuspendCheck();
333 }
334 ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
335 ::llvm::Value* src2 = GetLLVMValue(rl_src2.orig_sreg);
336 ::llvm::Value* cond_value = ConvertCompare(cc, src1, src2);
337 cond_value->setName(StringPrintf("t%d", temp_name_++));
buzbee0d829482013-10-11 15:24:55 -0700338 irb_->CreateCondBr(cond_value, GetLLVMBlock(bb->taken),
339 GetLLVMBlock(bb->fall_through));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700340 // Don't redo the fallthrough branch in the BB driver
buzbee0d829482013-10-11 15:24:55 -0700341 bb->fall_through = NullBasicBlockId;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700342}
343
344void MirConverter::ConvertCompareZeroAndBranch(BasicBlock* bb,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700345 MIR* mir, ConditionCode cc, RegLocation rl_src1) {
buzbee0d829482013-10-11 15:24:55 -0700346 if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= mir->offset) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700347 EmitSuspendCheck();
348 }
349 ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
350 ::llvm::Value* src2;
351 if (rl_src1.ref) {
352 src2 = irb_->getJNull();
353 } else {
354 src2 = irb_->getInt32(0);
355 }
356 ::llvm::Value* cond_value = ConvertCompare(cc, src1, src2);
buzbee0d829482013-10-11 15:24:55 -0700357 irb_->CreateCondBr(cond_value, GetLLVMBlock(bb->taken),
358 GetLLVMBlock(bb->fall_through));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700359 // Don't redo the fallthrough branch in the BB driver
buzbee0d829482013-10-11 15:24:55 -0700360 bb->fall_through = NullBasicBlockId;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700361}
362
363::llvm::Value* MirConverter::GenDivModOp(bool is_div, bool is_long,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700364 ::llvm::Value* src1, ::llvm::Value* src2) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700365 art::llvm::IntrinsicHelper::IntrinsicId id;
366 if (is_long) {
367 if (is_div) {
368 id = art::llvm::IntrinsicHelper::DivLong;
369 } else {
370 id = art::llvm::IntrinsicHelper::RemLong;
371 }
372 } else {
373 if (is_div) {
374 id = art::llvm::IntrinsicHelper::DivInt;
375 } else {
376 id = art::llvm::IntrinsicHelper::RemInt;
377 }
378 }
379 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
380 ::llvm::SmallVector< ::llvm::Value*, 2>args;
381 args.push_back(src1);
382 args.push_back(src2);
383 return irb_->CreateCall(intr, args);
384}
385
386::llvm::Value* MirConverter::GenArithOp(OpKind op, bool is_long,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700387 ::llvm::Value* src1, ::llvm::Value* src2) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700388 ::llvm::Value* res = NULL;
Brian Carlstromdf629502013-07-17 22:39:56 -0700389 switch (op) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700390 case kOpAdd: res = irb_->CreateAdd(src1, src2); break;
391 case kOpSub: res = irb_->CreateSub(src1, src2); break;
392 case kOpRsub: res = irb_->CreateSub(src2, src1); break;
393 case kOpMul: res = irb_->CreateMul(src1, src2); break;
394 case kOpOr: res = irb_->CreateOr(src1, src2); break;
395 case kOpAnd: res = irb_->CreateAnd(src1, src2); break;
396 case kOpXor: res = irb_->CreateXor(src1, src2); break;
397 case kOpDiv: res = GenDivModOp(true, is_long, src1, src2); break;
398 case kOpRem: res = GenDivModOp(false, is_long, src1, src2); break;
399 case kOpLsl: res = irb_->CreateShl(src1, src2); break;
400 case kOpLsr: res = irb_->CreateLShr(src1, src2); break;
401 case kOpAsr: res = irb_->CreateAShr(src1, src2); break;
402 default:
403 LOG(FATAL) << "Invalid op " << op;
404 }
405 return res;
406}
407
408void MirConverter::ConvertFPArithOp(OpKind op, RegLocation rl_dest,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700409 RegLocation rl_src1, RegLocation rl_src2) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700410 ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
411 ::llvm::Value* src2 = GetLLVMValue(rl_src2.orig_sreg);
412 ::llvm::Value* res = NULL;
Brian Carlstromdf629502013-07-17 22:39:56 -0700413 switch (op) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700414 case kOpAdd: res = irb_->CreateFAdd(src1, src2); break;
415 case kOpSub: res = irb_->CreateFSub(src1, src2); break;
416 case kOpMul: res = irb_->CreateFMul(src1, src2); break;
417 case kOpDiv: res = irb_->CreateFDiv(src1, src2); break;
418 case kOpRem: res = irb_->CreateFRem(src1, src2); break;
419 default:
420 LOG(FATAL) << "Invalid op " << op;
421 }
422 DefineValue(res, rl_dest.orig_sreg);
423}
424
425void MirConverter::ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700426 RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700427 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
428 ::llvm::SmallVector< ::llvm::Value*, 2>args;
429 args.push_back(GetLLVMValue(rl_src1.orig_sreg));
430 args.push_back(GetLLVMValue(rl_src2.orig_sreg));
431 ::llvm::Value* res = irb_->CreateCall(intr, args);
432 DefineValue(res, rl_dest.orig_sreg);
433}
434
435void MirConverter::ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700436 RegLocation rl_dest, RegLocation rl_src, int shift_amount) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700437 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
438 ::llvm::SmallVector< ::llvm::Value*, 2>args;
439 args.push_back(GetLLVMValue(rl_src.orig_sreg));
440 args.push_back(irb_->getInt32(shift_amount));
441 ::llvm::Value* res = irb_->CreateCall(intr, args);
442 DefineValue(res, rl_dest.orig_sreg);
443}
444
445void MirConverter::ConvertArithOp(OpKind op, RegLocation rl_dest,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700446 RegLocation rl_src1, RegLocation rl_src2) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700447 ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
448 ::llvm::Value* src2 = GetLLVMValue(rl_src2.orig_sreg);
449 DCHECK_EQ(src1->getType(), src2->getType());
450 ::llvm::Value* res = GenArithOp(op, rl_dest.wide, src1, src2);
451 DefineValue(res, rl_dest.orig_sreg);
452}
453
454void MirConverter::ConvertArithOpLit(OpKind op, RegLocation rl_dest,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700455 RegLocation rl_src1, int32_t imm) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700456 ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
457 ::llvm::Value* src2 = irb_->getInt32(imm);
458 ::llvm::Value* res = GenArithOp(op, rl_dest.wide, src1, src2);
459 DefineValue(res, rl_dest.orig_sreg);
460}
461
462/*
463 * Process arguments for invoke. Note: this code is also used to
464 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
465 * The requirements are similar.
466 */
467void MirConverter::ConvertInvoke(BasicBlock* bb, MIR* mir,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700468 InvokeType invoke_type, bool is_range, bool is_filled_new_array) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700469 CallInfo* info = mir_graph_->NewMemCallInfo(bb, mir, invoke_type, is_range);
470 ::llvm::SmallVector< ::llvm::Value*, 10> args;
471 // Insert the invoke_type
472 args.push_back(irb_->getInt32(static_cast<int>(invoke_type)));
473 // Insert the method_idx
474 args.push_back(irb_->getInt32(info->index));
475 // Insert the optimization flags
476 args.push_back(irb_->getInt32(info->opt_flags));
477 // Now, insert the actual arguments
478 for (int i = 0; i < info->num_arg_words;) {
479 ::llvm::Value* val = GetLLVMValue(info->args[i].orig_sreg);
480 args.push_back(val);
481 i += info->args[i].wide ? 2 : 1;
482 }
483 /*
484 * Choose the invoke return type based on actual usage. Note: may
485 * be different than shorty. For example, if a function return value
486 * is not used, we'll treat this as a void invoke.
487 */
488 art::llvm::IntrinsicHelper::IntrinsicId id;
489 if (is_filled_new_array) {
490 id = art::llvm::IntrinsicHelper::HLFilledNewArray;
491 } else if (info->result.location == kLocInvalid) {
492 id = art::llvm::IntrinsicHelper::HLInvokeVoid;
493 } else {
494 if (info->result.wide) {
495 if (info->result.fp) {
496 id = art::llvm::IntrinsicHelper::HLInvokeDouble;
497 } else {
498 id = art::llvm::IntrinsicHelper::HLInvokeLong;
499 }
500 } else if (info->result.ref) {
501 id = art::llvm::IntrinsicHelper::HLInvokeObj;
502 } else if (info->result.fp) {
503 id = art::llvm::IntrinsicHelper::HLInvokeFloat;
504 } else {
505 id = art::llvm::IntrinsicHelper::HLInvokeInt;
506 }
507 }
508 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
509 ::llvm::Value* res = irb_->CreateCall(intr, args);
510 if (info->result.location != kLocInvalid) {
511 DefineValue(res, info->result.orig_sreg);
512 }
513}
514
515void MirConverter::ConvertConstObject(uint32_t idx,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700516 art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700517 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
518 ::llvm::Value* index = irb_->getInt32(idx);
519 ::llvm::Value* res = irb_->CreateCall(intr, index);
520 DefineValue(res, rl_dest.orig_sreg);
521}
522
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700523void MirConverter::ConvertCheckCast(uint32_t type_idx, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700524 art::llvm::IntrinsicHelper::IntrinsicId id;
525 id = art::llvm::IntrinsicHelper::HLCheckCast;
526 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
527 ::llvm::SmallVector< ::llvm::Value*, 2> args;
528 args.push_back(irb_->getInt32(type_idx));
529 args.push_back(GetLLVMValue(rl_src.orig_sreg));
530 irb_->CreateCall(intr, args);
531}
532
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700533void MirConverter::ConvertNewInstance(uint32_t type_idx, RegLocation rl_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700534 art::llvm::IntrinsicHelper::IntrinsicId id;
535 id = art::llvm::IntrinsicHelper::NewInstance;
536 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
537 ::llvm::Value* index = irb_->getInt32(type_idx);
538 ::llvm::Value* res = irb_->CreateCall(intr, index);
539 DefineValue(res, rl_dest.orig_sreg);
540}
541
542void MirConverter::ConvertNewArray(uint32_t type_idx,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700543 RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700544 art::llvm::IntrinsicHelper::IntrinsicId id;
545 id = art::llvm::IntrinsicHelper::NewArray;
546 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
547 ::llvm::SmallVector< ::llvm::Value*, 2> args;
548 args.push_back(irb_->getInt32(type_idx));
549 args.push_back(GetLLVMValue(rl_src.orig_sreg));
550 ::llvm::Value* res = irb_->CreateCall(intr, args);
551 DefineValue(res, rl_dest.orig_sreg);
552}
553
554void MirConverter::ConvertAget(int opt_flags,
555 art::llvm::IntrinsicHelper::IntrinsicId id,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700556 RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700557 ::llvm::SmallVector< ::llvm::Value*, 3> args;
558 args.push_back(irb_->getInt32(opt_flags));
559 args.push_back(GetLLVMValue(rl_array.orig_sreg));
560 args.push_back(GetLLVMValue(rl_index.orig_sreg));
561 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
562 ::llvm::Value* res = irb_->CreateCall(intr, args);
563 DefineValue(res, rl_dest.orig_sreg);
564}
565
566void MirConverter::ConvertAput(int opt_flags,
567 art::llvm::IntrinsicHelper::IntrinsicId id,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700568 RegLocation rl_src, RegLocation rl_array, RegLocation rl_index) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700569 ::llvm::SmallVector< ::llvm::Value*, 4> args;
570 args.push_back(irb_->getInt32(opt_flags));
571 args.push_back(GetLLVMValue(rl_src.orig_sreg));
572 args.push_back(GetLLVMValue(rl_array.orig_sreg));
573 args.push_back(GetLLVMValue(rl_index.orig_sreg));
574 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
575 irb_->CreateCall(intr, args);
576}
577
578void MirConverter::ConvertIget(int opt_flags,
579 art::llvm::IntrinsicHelper::IntrinsicId id,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700580 RegLocation rl_dest, RegLocation rl_obj, int field_index) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700581 ::llvm::SmallVector< ::llvm::Value*, 3> args;
582 args.push_back(irb_->getInt32(opt_flags));
583 args.push_back(GetLLVMValue(rl_obj.orig_sreg));
584 args.push_back(irb_->getInt32(field_index));
585 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
586 ::llvm::Value* res = irb_->CreateCall(intr, args);
587 DefineValue(res, rl_dest.orig_sreg);
588}
589
590void MirConverter::ConvertIput(int opt_flags,
591 art::llvm::IntrinsicHelper::IntrinsicId id,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700592 RegLocation rl_src, RegLocation rl_obj, int field_index) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700593 ::llvm::SmallVector< ::llvm::Value*, 4> args;
594 args.push_back(irb_->getInt32(opt_flags));
595 args.push_back(GetLLVMValue(rl_src.orig_sreg));
596 args.push_back(GetLLVMValue(rl_obj.orig_sreg));
597 args.push_back(irb_->getInt32(field_index));
598 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
599 irb_->CreateCall(intr, args);
600}
601
602void MirConverter::ConvertInstanceOf(uint32_t type_idx,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700603 RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700604 art::llvm::IntrinsicHelper::IntrinsicId id;
605 id = art::llvm::IntrinsicHelper::InstanceOf;
606 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
607 ::llvm::SmallVector< ::llvm::Value*, 2> args;
608 args.push_back(irb_->getInt32(type_idx));
609 args.push_back(GetLLVMValue(rl_src.orig_sreg));
610 ::llvm::Value* res = irb_->CreateCall(intr, args);
611 DefineValue(res, rl_dest.orig_sreg);
612}
613
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700614void MirConverter::ConvertIntToLong(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700615 ::llvm::Value* res = irb_->CreateSExt(GetLLVMValue(rl_src.orig_sreg),
616 irb_->getInt64Ty());
617 DefineValue(res, rl_dest.orig_sreg);
618}
619
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700620void MirConverter::ConvertLongToInt(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700621 ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg);
622 ::llvm::Value* res = irb_->CreateTrunc(src, irb_->getInt32Ty());
623 DefineValue(res, rl_dest.orig_sreg);
624}
625
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700626void MirConverter::ConvertFloatToDouble(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700627 ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg);
628 ::llvm::Value* res = irb_->CreateFPExt(src, irb_->getDoubleTy());
629 DefineValue(res, rl_dest.orig_sreg);
630}
631
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700632void MirConverter::ConvertDoubleToFloat(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700633 ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg);
634 ::llvm::Value* res = irb_->CreateFPTrunc(src, irb_->getFloatTy());
635 DefineValue(res, rl_dest.orig_sreg);
636}
637
638void MirConverter::ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id,
639 RegLocation rl_dest, RegLocation rl_src1,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700640 RegLocation rl_src2) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700641 DCHECK_EQ(rl_src1.fp, rl_src2.fp);
642 DCHECK_EQ(rl_src1.wide, rl_src2.wide);
643 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
644 ::llvm::SmallVector< ::llvm::Value*, 2> args;
645 args.push_back(GetLLVMValue(rl_src1.orig_sreg));
646 args.push_back(GetLLVMValue(rl_src2.orig_sreg));
647 ::llvm::Value* res = irb_->CreateCall(intr, args);
648 DefineValue(res, rl_dest.orig_sreg);
649}
650
651void MirConverter::ConvertIntNarrowing(RegLocation rl_dest, RegLocation rl_src,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700652 art::llvm::IntrinsicHelper::IntrinsicId id) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700653 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
654 ::llvm::Value* res =
655 irb_->CreateCall(intr, GetLLVMValue(rl_src.orig_sreg));
656 DefineValue(res, rl_dest.orig_sreg);
657}
658
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700659void MirConverter::ConvertNeg(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700660 ::llvm::Value* res = irb_->CreateNeg(GetLLVMValue(rl_src.orig_sreg));
661 DefineValue(res, rl_dest.orig_sreg);
662}
663
664void MirConverter::ConvertIntToFP(::llvm::Type* ty, RegLocation rl_dest,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700665 RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700666 ::llvm::Value* res =
667 irb_->CreateSIToFP(GetLLVMValue(rl_src.orig_sreg), ty);
668 DefineValue(res, rl_dest.orig_sreg);
669}
670
671void MirConverter::ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id,
672 RegLocation rl_dest,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700673 RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700674 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
675 ::llvm::Value* res = irb_->CreateCall(intr, GetLLVMValue(rl_src.orig_sreg));
676 DefineValue(res, rl_dest.orig_sreg);
677}
678
679
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700680void MirConverter::ConvertNegFP(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700681 ::llvm::Value* res =
682 irb_->CreateFNeg(GetLLVMValue(rl_src.orig_sreg));
683 DefineValue(res, rl_dest.orig_sreg);
684}
685
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700686void MirConverter::ConvertNot(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700687 ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg);
688 ::llvm::Value* res = irb_->CreateXor(src, static_cast<uint64_t>(-1));
689 DefineValue(res, rl_dest.orig_sreg);
690}
691
692void MirConverter::EmitConstructorBarrier() {
693 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(
694 art::llvm::IntrinsicHelper::ConstructorBarrier);
695 irb_->CreateCall(intr);
696}
697
698/*
699 * Target-independent code generation. Use only high-level
700 * load/store utilities here, or target-dependent genXX() handlers
701 * when necessary.
702 */
703bool MirConverter::ConvertMIRNode(MIR* mir, BasicBlock* bb,
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700704 ::llvm::BasicBlock* llvm_bb) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700705 bool res = false; // Assume success
706 RegLocation rl_src[3];
707 RegLocation rl_dest = mir_graph_->GetBadLoc();
708 Instruction::Code opcode = mir->dalvikInsn.opcode;
709 int op_val = opcode;
710 uint32_t vB = mir->dalvikInsn.vB;
711 uint32_t vC = mir->dalvikInsn.vC;
712 int opt_flags = mir->optimization_flags;
713
714 if (cu_->verbose) {
buzbee35ba7f32014-05-31 08:59:01 -0700715 if (!IsPseudoMirOp(op_val)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700716 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << op_val;
717 } else {
718 LOG(INFO) << mir_graph_->extended_mir_op_names_[op_val - kMirOpFirst] << " 0x" << std::hex << op_val;
719 }
720 }
721
722 /* Prep Src and Dest locations */
723 int next_sreg = 0;
724 int next_loc = 0;
Jean Christophe Beylercc794c32014-05-02 09:34:13 -0700725 uint64_t attrs = MirGraph::GetDataFlowAttributes(opcode);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700726 rl_src[0] = rl_src[1] = rl_src[2] = mir_graph_->GetBadLoc();
727 if (attrs & DF_UA) {
728 if (attrs & DF_A_WIDE) {
729 rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg);
730 next_sreg+= 2;
731 } else {
732 rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg);
733 next_sreg++;
734 }
735 }
736 if (attrs & DF_UB) {
737 if (attrs & DF_B_WIDE) {
738 rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg);
739 next_sreg+= 2;
740 } else {
741 rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg);
742 next_sreg++;
743 }
744 }
745 if (attrs & DF_UC) {
746 if (attrs & DF_C_WIDE) {
747 rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg);
748 } else {
749 rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg);
750 }
751 }
752 if (attrs & DF_DA) {
753 if (attrs & DF_A_WIDE) {
754 rl_dest = mir_graph_->GetDestWide(mir);
755 } else {
756 rl_dest = mir_graph_->GetDest(mir);
757 }
758 }
759
760 switch (opcode) {
761 case Instruction::NOP:
762 break;
763
764 case Instruction::MOVE:
765 case Instruction::MOVE_OBJECT:
766 case Instruction::MOVE_16:
767 case Instruction::MOVE_OBJECT_16:
768 case Instruction::MOVE_OBJECT_FROM16:
769 case Instruction::MOVE_FROM16:
770 case Instruction::MOVE_WIDE:
771 case Instruction::MOVE_WIDE_16:
772 case Instruction::MOVE_WIDE_FROM16: {
773 /*
774 * Moves/copies are meaningless in pure SSA register form,
775 * but we need to preserve them for the conversion back into
776 * MIR (at least until we stop using the Dalvik register maps).
777 * Insert a dummy intrinsic copy call, which will be recognized
778 * by the quick path and removed by the portable path.
779 */
780 ::llvm::Value* src = GetLLVMValue(rl_src[0].orig_sreg);
781 ::llvm::Value* res = EmitCopy(src, rl_dest);
782 DefineValue(res, rl_dest.orig_sreg);
783 }
784 break;
785
786 case Instruction::CONST:
787 case Instruction::CONST_4:
788 case Instruction::CONST_16: {
789 ::llvm::Constant* imm_value = irb_->getJInt(vB);
790 ::llvm::Value* res = EmitConst(imm_value, rl_dest);
791 DefineValue(res, rl_dest.orig_sreg);
792 }
793 break;
794
795 case Instruction::CONST_WIDE_16:
796 case Instruction::CONST_WIDE_32: {
797 // Sign extend to 64 bits
798 int64_t imm = static_cast<int32_t>(vB);
799 ::llvm::Constant* imm_value = irb_->getJLong(imm);
800 ::llvm::Value* res = EmitConst(imm_value, rl_dest);
801 DefineValue(res, rl_dest.orig_sreg);
802 }
803 break;
804
805 case Instruction::CONST_HIGH16: {
806 ::llvm::Constant* imm_value = irb_->getJInt(vB << 16);
807 ::llvm::Value* res = EmitConst(imm_value, rl_dest);
808 DefineValue(res, rl_dest.orig_sreg);
809 }
810 break;
811
812 case Instruction::CONST_WIDE: {
813 ::llvm::Constant* imm_value =
814 irb_->getJLong(mir->dalvikInsn.vB_wide);
815 ::llvm::Value* res = EmitConst(imm_value, rl_dest);
816 DefineValue(res, rl_dest.orig_sreg);
817 }
818 break;
819 case Instruction::CONST_WIDE_HIGH16: {
820 int64_t imm = static_cast<int64_t>(vB) << 48;
821 ::llvm::Constant* imm_value = irb_->getJLong(imm);
822 ::llvm::Value* res = EmitConst(imm_value, rl_dest);
823 DefineValue(res, rl_dest.orig_sreg);
824 }
825 break;
826
827 case Instruction::SPUT_OBJECT:
828 ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputObject,
829 rl_src[0]);
830 break;
831 case Instruction::SPUT:
832 if (rl_src[0].fp) {
833 ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputFloat,
834 rl_src[0]);
835 } else {
836 ConvertSput(vB, art::llvm::IntrinsicHelper::HLSput, rl_src[0]);
837 }
838 break;
839 case Instruction::SPUT_BOOLEAN:
840 ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputBoolean,
841 rl_src[0]);
842 break;
843 case Instruction::SPUT_BYTE:
844 ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputByte, rl_src[0]);
845 break;
846 case Instruction::SPUT_CHAR:
847 ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputChar, rl_src[0]);
848 break;
849 case Instruction::SPUT_SHORT:
850 ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputShort, rl_src[0]);
851 break;
852 case Instruction::SPUT_WIDE:
853 if (rl_src[0].fp) {
854 ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputDouble,
855 rl_src[0]);
856 } else {
857 ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputWide,
858 rl_src[0]);
859 }
860 break;
861
862 case Instruction::SGET_OBJECT:
863 ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetObject, rl_dest);
864 break;
865 case Instruction::SGET:
866 if (rl_dest.fp) {
867 ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetFloat, rl_dest);
868 } else {
869 ConvertSget(vB, art::llvm::IntrinsicHelper::HLSget, rl_dest);
870 }
871 break;
872 case Instruction::SGET_BOOLEAN:
873 ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetBoolean, rl_dest);
874 break;
875 case Instruction::SGET_BYTE:
876 ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetByte, rl_dest);
877 break;
878 case Instruction::SGET_CHAR:
879 ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetChar, rl_dest);
880 break;
881 case Instruction::SGET_SHORT:
882 ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetShort, rl_dest);
883 break;
884 case Instruction::SGET_WIDE:
885 if (rl_dest.fp) {
886 ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetDouble,
887 rl_dest);
888 } else {
889 ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetWide, rl_dest);
890 }
891 break;
892
893 case Instruction::RETURN_WIDE:
894 case Instruction::RETURN:
895 case Instruction::RETURN_OBJECT: {
896 if (!mir_graph_->MethodIsLeaf()) {
897 EmitSuspendCheck();
898 }
899 EmitPopShadowFrame();
900 irb_->CreateRet(GetLLVMValue(rl_src[0].orig_sreg));
901 DCHECK(bb->terminated_by_return);
902 }
903 break;
904
905 case Instruction::RETURN_VOID: {
906 if (((cu_->access_flags & kAccConstructor) != 0) &&
907 cu_->compiler_driver->RequiresConstructorBarrier(Thread::Current(),
908 cu_->dex_file,
909 cu_->class_def_idx)) {
910 EmitConstructorBarrier();
911 }
912 if (!mir_graph_->MethodIsLeaf()) {
913 EmitSuspendCheck();
914 }
915 EmitPopShadowFrame();
916 irb_->CreateRetVoid();
917 DCHECK(bb->terminated_by_return);
918 }
919 break;
920
921 case Instruction::IF_EQ:
922 ConvertCompareAndBranch(bb, mir, kCondEq, rl_src[0], rl_src[1]);
923 break;
924 case Instruction::IF_NE:
925 ConvertCompareAndBranch(bb, mir, kCondNe, rl_src[0], rl_src[1]);
926 break;
927 case Instruction::IF_LT:
928 ConvertCompareAndBranch(bb, mir, kCondLt, rl_src[0], rl_src[1]);
929 break;
930 case Instruction::IF_GE:
931 ConvertCompareAndBranch(bb, mir, kCondGe, rl_src[0], rl_src[1]);
932 break;
933 case Instruction::IF_GT:
934 ConvertCompareAndBranch(bb, mir, kCondGt, rl_src[0], rl_src[1]);
935 break;
936 case Instruction::IF_LE:
937 ConvertCompareAndBranch(bb, mir, kCondLe, rl_src[0], rl_src[1]);
938 break;
939 case Instruction::IF_EQZ:
940 ConvertCompareZeroAndBranch(bb, mir, kCondEq, rl_src[0]);
941 break;
942 case Instruction::IF_NEZ:
943 ConvertCompareZeroAndBranch(bb, mir, kCondNe, rl_src[0]);
944 break;
945 case Instruction::IF_LTZ:
946 ConvertCompareZeroAndBranch(bb, mir, kCondLt, rl_src[0]);
947 break;
948 case Instruction::IF_GEZ:
949 ConvertCompareZeroAndBranch(bb, mir, kCondGe, rl_src[0]);
950 break;
951 case Instruction::IF_GTZ:
952 ConvertCompareZeroAndBranch(bb, mir, kCondGt, rl_src[0]);
953 break;
954 case Instruction::IF_LEZ:
955 ConvertCompareZeroAndBranch(bb, mir, kCondLe, rl_src[0]);
956 break;
957
958 case Instruction::GOTO:
959 case Instruction::GOTO_16:
960 case Instruction::GOTO_32: {
buzbee0d829482013-10-11 15:24:55 -0700961 if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= bb->start_offset) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700962 EmitSuspendCheck();
963 }
buzbee0d829482013-10-11 15:24:55 -0700964 irb_->CreateBr(GetLLVMBlock(bb->taken));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700965 }
966 break;
967
968 case Instruction::ADD_LONG:
969 case Instruction::ADD_LONG_2ADDR:
970 case Instruction::ADD_INT:
971 case Instruction::ADD_INT_2ADDR:
972 ConvertArithOp(kOpAdd, rl_dest, rl_src[0], rl_src[1]);
973 break;
974 case Instruction::SUB_LONG:
975 case Instruction::SUB_LONG_2ADDR:
976 case Instruction::SUB_INT:
977 case Instruction::SUB_INT_2ADDR:
978 ConvertArithOp(kOpSub, rl_dest, rl_src[0], rl_src[1]);
979 break;
980 case Instruction::MUL_LONG:
981 case Instruction::MUL_LONG_2ADDR:
982 case Instruction::MUL_INT:
983 case Instruction::MUL_INT_2ADDR:
984 ConvertArithOp(kOpMul, rl_dest, rl_src[0], rl_src[1]);
985 break;
986 case Instruction::DIV_LONG:
987 case Instruction::DIV_LONG_2ADDR:
988 case Instruction::DIV_INT:
989 case Instruction::DIV_INT_2ADDR:
990 ConvertArithOp(kOpDiv, rl_dest, rl_src[0], rl_src[1]);
991 break;
992 case Instruction::REM_LONG:
993 case Instruction::REM_LONG_2ADDR:
994 case Instruction::REM_INT:
995 case Instruction::REM_INT_2ADDR:
996 ConvertArithOp(kOpRem, rl_dest, rl_src[0], rl_src[1]);
997 break;
998 case Instruction::AND_LONG:
999 case Instruction::AND_LONG_2ADDR:
1000 case Instruction::AND_INT:
1001 case Instruction::AND_INT_2ADDR:
1002 ConvertArithOp(kOpAnd, rl_dest, rl_src[0], rl_src[1]);
1003 break;
1004 case Instruction::OR_LONG:
1005 case Instruction::OR_LONG_2ADDR:
1006 case Instruction::OR_INT:
1007 case Instruction::OR_INT_2ADDR:
1008 ConvertArithOp(kOpOr, rl_dest, rl_src[0], rl_src[1]);
1009 break;
1010 case Instruction::XOR_LONG:
1011 case Instruction::XOR_LONG_2ADDR:
1012 case Instruction::XOR_INT:
1013 case Instruction::XOR_INT_2ADDR:
1014 ConvertArithOp(kOpXor, rl_dest, rl_src[0], rl_src[1]);
1015 break;
1016 case Instruction::SHL_LONG:
1017 case Instruction::SHL_LONG_2ADDR:
1018 ConvertShift(art::llvm::IntrinsicHelper::SHLLong,
1019 rl_dest, rl_src[0], rl_src[1]);
1020 break;
1021 case Instruction::SHL_INT:
1022 case Instruction::SHL_INT_2ADDR:
1023 ConvertShift(art::llvm::IntrinsicHelper::SHLInt,
1024 rl_dest, rl_src[0], rl_src[1]);
1025 break;
1026 case Instruction::SHR_LONG:
1027 case Instruction::SHR_LONG_2ADDR:
1028 ConvertShift(art::llvm::IntrinsicHelper::SHRLong,
1029 rl_dest, rl_src[0], rl_src[1]);
1030 break;
1031 case Instruction::SHR_INT:
1032 case Instruction::SHR_INT_2ADDR:
1033 ConvertShift(art::llvm::IntrinsicHelper::SHRInt,
1034 rl_dest, rl_src[0], rl_src[1]);
1035 break;
1036 case Instruction::USHR_LONG:
1037 case Instruction::USHR_LONG_2ADDR:
1038 ConvertShift(art::llvm::IntrinsicHelper::USHRLong,
1039 rl_dest, rl_src[0], rl_src[1]);
1040 break;
1041 case Instruction::USHR_INT:
1042 case Instruction::USHR_INT_2ADDR:
1043 ConvertShift(art::llvm::IntrinsicHelper::USHRInt,
1044 rl_dest, rl_src[0], rl_src[1]);
1045 break;
1046
1047 case Instruction::ADD_INT_LIT16:
1048 case Instruction::ADD_INT_LIT8:
1049 ConvertArithOpLit(kOpAdd, rl_dest, rl_src[0], vC);
1050 break;
1051 case Instruction::RSUB_INT:
1052 case Instruction::RSUB_INT_LIT8:
1053 ConvertArithOpLit(kOpRsub, rl_dest, rl_src[0], vC);
1054 break;
1055 case Instruction::MUL_INT_LIT16:
1056 case Instruction::MUL_INT_LIT8:
1057 ConvertArithOpLit(kOpMul, rl_dest, rl_src[0], vC);
1058 break;
1059 case Instruction::DIV_INT_LIT16:
1060 case Instruction::DIV_INT_LIT8:
1061 ConvertArithOpLit(kOpDiv, rl_dest, rl_src[0], vC);
1062 break;
1063 case Instruction::REM_INT_LIT16:
1064 case Instruction::REM_INT_LIT8:
1065 ConvertArithOpLit(kOpRem, rl_dest, rl_src[0], vC);
1066 break;
1067 case Instruction::AND_INT_LIT16:
1068 case Instruction::AND_INT_LIT8:
1069 ConvertArithOpLit(kOpAnd, rl_dest, rl_src[0], vC);
1070 break;
1071 case Instruction::OR_INT_LIT16:
1072 case Instruction::OR_INT_LIT8:
1073 ConvertArithOpLit(kOpOr, rl_dest, rl_src[0], vC);
1074 break;
1075 case Instruction::XOR_INT_LIT16:
1076 case Instruction::XOR_INT_LIT8:
1077 ConvertArithOpLit(kOpXor, rl_dest, rl_src[0], vC);
1078 break;
1079 case Instruction::SHL_INT_LIT8:
1080 ConvertShiftLit(art::llvm::IntrinsicHelper::SHLInt,
1081 rl_dest, rl_src[0], vC & 0x1f);
1082 break;
1083 case Instruction::SHR_INT_LIT8:
1084 ConvertShiftLit(art::llvm::IntrinsicHelper::SHRInt,
1085 rl_dest, rl_src[0], vC & 0x1f);
1086 break;
1087 case Instruction::USHR_INT_LIT8:
1088 ConvertShiftLit(art::llvm::IntrinsicHelper::USHRInt,
1089 rl_dest, rl_src[0], vC & 0x1f);
1090 break;
1091
1092 case Instruction::ADD_FLOAT:
1093 case Instruction::ADD_FLOAT_2ADDR:
1094 case Instruction::ADD_DOUBLE:
1095 case Instruction::ADD_DOUBLE_2ADDR:
1096 ConvertFPArithOp(kOpAdd, rl_dest, rl_src[0], rl_src[1]);
1097 break;
1098
1099 case Instruction::SUB_FLOAT:
1100 case Instruction::SUB_FLOAT_2ADDR:
1101 case Instruction::SUB_DOUBLE:
1102 case Instruction::SUB_DOUBLE_2ADDR:
1103 ConvertFPArithOp(kOpSub, rl_dest, rl_src[0], rl_src[1]);
1104 break;
1105
1106 case Instruction::MUL_FLOAT:
1107 case Instruction::MUL_FLOAT_2ADDR:
1108 case Instruction::MUL_DOUBLE:
1109 case Instruction::MUL_DOUBLE_2ADDR:
1110 ConvertFPArithOp(kOpMul, rl_dest, rl_src[0], rl_src[1]);
1111 break;
1112
1113 case Instruction::DIV_FLOAT:
1114 case Instruction::DIV_FLOAT_2ADDR:
1115 case Instruction::DIV_DOUBLE:
1116 case Instruction::DIV_DOUBLE_2ADDR:
1117 ConvertFPArithOp(kOpDiv, rl_dest, rl_src[0], rl_src[1]);
1118 break;
1119
1120 case Instruction::REM_FLOAT:
1121 case Instruction::REM_FLOAT_2ADDR:
1122 case Instruction::REM_DOUBLE:
1123 case Instruction::REM_DOUBLE_2ADDR:
1124 ConvertFPArithOp(kOpRem, rl_dest, rl_src[0], rl_src[1]);
1125 break;
1126
1127 case Instruction::INVOKE_STATIC:
1128 ConvertInvoke(bb, mir, kStatic, false /*range*/,
1129 false /* NewFilledArray */);
1130 break;
1131 case Instruction::INVOKE_STATIC_RANGE:
1132 ConvertInvoke(bb, mir, kStatic, true /*range*/,
1133 false /* NewFilledArray */);
1134 break;
1135
1136 case Instruction::INVOKE_DIRECT:
1137 ConvertInvoke(bb, mir, kDirect, false /*range*/,
1138 false /* NewFilledArray */);
1139 break;
1140 case Instruction::INVOKE_DIRECT_RANGE:
1141 ConvertInvoke(bb, mir, kDirect, true /*range*/,
1142 false /* NewFilledArray */);
1143 break;
1144
1145 case Instruction::INVOKE_VIRTUAL:
1146 ConvertInvoke(bb, mir, kVirtual, false /*range*/,
1147 false /* NewFilledArray */);
1148 break;
1149 case Instruction::INVOKE_VIRTUAL_RANGE:
1150 ConvertInvoke(bb, mir, kVirtual, true /*range*/,
1151 false /* NewFilledArray */);
1152 break;
1153
1154 case Instruction::INVOKE_SUPER:
1155 ConvertInvoke(bb, mir, kSuper, false /*range*/,
1156 false /* NewFilledArray */);
1157 break;
1158 case Instruction::INVOKE_SUPER_RANGE:
1159 ConvertInvoke(bb, mir, kSuper, true /*range*/,
1160 false /* NewFilledArray */);
1161 break;
1162
1163 case Instruction::INVOKE_INTERFACE:
1164 ConvertInvoke(bb, mir, kInterface, false /*range*/,
1165 false /* NewFilledArray */);
1166 break;
1167 case Instruction::INVOKE_INTERFACE_RANGE:
1168 ConvertInvoke(bb, mir, kInterface, true /*range*/,
1169 false /* NewFilledArray */);
1170 break;
1171 case Instruction::FILLED_NEW_ARRAY:
1172 ConvertInvoke(bb, mir, kInterface, false /*range*/,
1173 true /* NewFilledArray */);
1174 break;
1175 case Instruction::FILLED_NEW_ARRAY_RANGE:
1176 ConvertInvoke(bb, mir, kInterface, true /*range*/,
1177 true /* NewFilledArray */);
1178 break;
1179
1180 case Instruction::CONST_STRING:
1181 case Instruction::CONST_STRING_JUMBO:
1182 ConvertConstObject(vB, art::llvm::IntrinsicHelper::ConstString,
1183 rl_dest);
1184 break;
1185
1186 case Instruction::CONST_CLASS:
1187 ConvertConstObject(vB, art::llvm::IntrinsicHelper::ConstClass,
1188 rl_dest);
1189 break;
1190
1191 case Instruction::CHECK_CAST:
1192 ConvertCheckCast(vB, rl_src[0]);
1193 break;
1194
1195 case Instruction::NEW_INSTANCE:
1196 ConvertNewInstance(vB, rl_dest);
1197 break;
1198
Brian Carlstrom6f485c62013-07-18 15:35:35 -07001199 case Instruction::MOVE_EXCEPTION:
Brian Carlstrom7940e442013-07-12 13:46:57 -07001200 ConvertMoveException(rl_dest);
1201 break;
1202
Brian Carlstrom6f485c62013-07-18 15:35:35 -07001203 case Instruction::THROW:
Brian Carlstrom7940e442013-07-12 13:46:57 -07001204 ConvertThrow(rl_src[0]);
1205 /*
1206 * If this throw is standalone, terminate.
1207 * If it might rethrow, force termination
1208 * of the following block.
1209 */
buzbee0d829482013-10-11 15:24:55 -07001210 if (bb->fall_through == NullBasicBlockId) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001211 irb_->CreateUnreachable();
1212 } else {
buzbee0d829482013-10-11 15:24:55 -07001213 mir_graph_->GetBasicBlock(bb->fall_through)->fall_through = NullBasicBlockId;
1214 mir_graph_->GetBasicBlock(bb->fall_through)->taken = NullBasicBlockId;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001215 }
1216 break;
1217
1218 case Instruction::MOVE_RESULT_WIDE:
1219 case Instruction::MOVE_RESULT:
1220 case Instruction::MOVE_RESULT_OBJECT:
1221 /*
1222 * All move_results should have been folded into the preceeding invoke.
1223 */
1224 LOG(FATAL) << "Unexpected move_result";
1225 break;
1226
1227 case Instruction::MONITOR_ENTER:
1228 ConvertMonitorEnterExit(opt_flags,
1229 art::llvm::IntrinsicHelper::MonitorEnter,
1230 rl_src[0]);
1231 break;
1232
1233 case Instruction::MONITOR_EXIT:
1234 ConvertMonitorEnterExit(opt_flags,
1235 art::llvm::IntrinsicHelper::MonitorExit,
1236 rl_src[0]);
1237 break;
1238
1239 case Instruction::ARRAY_LENGTH:
1240 ConvertArrayLength(opt_flags, rl_dest, rl_src[0]);
1241 break;
1242
1243 case Instruction::NEW_ARRAY:
1244 ConvertNewArray(vC, rl_dest, rl_src[0]);
1245 break;
1246
1247 case Instruction::INSTANCE_OF:
1248 ConvertInstanceOf(vC, rl_dest, rl_src[0]);
1249 break;
1250
1251 case Instruction::AGET:
1252 if (rl_dest.fp) {
1253 ConvertAget(opt_flags,
1254 art::llvm::IntrinsicHelper::HLArrayGetFloat,
1255 rl_dest, rl_src[0], rl_src[1]);
1256 } else {
1257 ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGet,
1258 rl_dest, rl_src[0], rl_src[1]);
1259 }
1260 break;
1261 case Instruction::AGET_OBJECT:
1262 ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetObject,
1263 rl_dest, rl_src[0], rl_src[1]);
1264 break;
1265 case Instruction::AGET_BOOLEAN:
1266 ConvertAget(opt_flags,
1267 art::llvm::IntrinsicHelper::HLArrayGetBoolean,
1268 rl_dest, rl_src[0], rl_src[1]);
1269 break;
1270 case Instruction::AGET_BYTE:
1271 ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetByte,
1272 rl_dest, rl_src[0], rl_src[1]);
1273 break;
1274 case Instruction::AGET_CHAR:
1275 ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetChar,
1276 rl_dest, rl_src[0], rl_src[1]);
1277 break;
1278 case Instruction::AGET_SHORT:
1279 ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetShort,
1280 rl_dest, rl_src[0], rl_src[1]);
1281 break;
1282 case Instruction::AGET_WIDE:
1283 if (rl_dest.fp) {
1284 ConvertAget(opt_flags,
1285 art::llvm::IntrinsicHelper::HLArrayGetDouble,
1286 rl_dest, rl_src[0], rl_src[1]);
1287 } else {
1288 ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetWide,
1289 rl_dest, rl_src[0], rl_src[1]);
1290 }
1291 break;
1292
1293 case Instruction::APUT:
1294 if (rl_src[0].fp) {
1295 ConvertAput(opt_flags,
1296 art::llvm::IntrinsicHelper::HLArrayPutFloat,
1297 rl_src[0], rl_src[1], rl_src[2]);
1298 } else {
1299 ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPut,
1300 rl_src[0], rl_src[1], rl_src[2]);
1301 }
1302 break;
1303 case Instruction::APUT_OBJECT:
1304 ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutObject,
1305 rl_src[0], rl_src[1], rl_src[2]);
1306 break;
1307 case Instruction::APUT_BOOLEAN:
1308 ConvertAput(opt_flags,
1309 art::llvm::IntrinsicHelper::HLArrayPutBoolean,
1310 rl_src[0], rl_src[1], rl_src[2]);
1311 break;
1312 case Instruction::APUT_BYTE:
1313 ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutByte,
1314 rl_src[0], rl_src[1], rl_src[2]);
1315 break;
1316 case Instruction::APUT_CHAR:
1317 ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutChar,
1318 rl_src[0], rl_src[1], rl_src[2]);
1319 break;
1320 case Instruction::APUT_SHORT:
1321 ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutShort,
1322 rl_src[0], rl_src[1], rl_src[2]);
1323 break;
1324 case Instruction::APUT_WIDE:
1325 if (rl_src[0].fp) {
1326 ConvertAput(opt_flags,
1327 art::llvm::IntrinsicHelper::HLArrayPutDouble,
1328 rl_src[0], rl_src[1], rl_src[2]);
1329 } else {
1330 ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutWide,
1331 rl_src[0], rl_src[1], rl_src[2]);
1332 }
1333 break;
1334
1335 case Instruction::IGET:
1336 if (rl_dest.fp) {
1337 ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetFloat,
1338 rl_dest, rl_src[0], vC);
1339 } else {
1340 ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGet,
1341 rl_dest, rl_src[0], vC);
1342 }
1343 break;
1344 case Instruction::IGET_OBJECT:
1345 ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetObject,
1346 rl_dest, rl_src[0], vC);
1347 break;
1348 case Instruction::IGET_BOOLEAN:
1349 ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetBoolean,
1350 rl_dest, rl_src[0], vC);
1351 break;
1352 case Instruction::IGET_BYTE:
1353 ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetByte,
1354 rl_dest, rl_src[0], vC);
1355 break;
1356 case Instruction::IGET_CHAR:
1357 ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetChar,
1358 rl_dest, rl_src[0], vC);
1359 break;
1360 case Instruction::IGET_SHORT:
1361 ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetShort,
1362 rl_dest, rl_src[0], vC);
1363 break;
1364 case Instruction::IGET_WIDE:
1365 if (rl_dest.fp) {
1366 ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetDouble,
1367 rl_dest, rl_src[0], vC);
1368 } else {
1369 ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetWide,
1370 rl_dest, rl_src[0], vC);
1371 }
1372 break;
1373 case Instruction::IPUT:
1374 if (rl_src[0].fp) {
1375 ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutFloat,
1376 rl_src[0], rl_src[1], vC);
1377 } else {
1378 ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPut,
1379 rl_src[0], rl_src[1], vC);
1380 }
1381 break;
1382 case Instruction::IPUT_OBJECT:
1383 ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutObject,
1384 rl_src[0], rl_src[1], vC);
1385 break;
1386 case Instruction::IPUT_BOOLEAN:
1387 ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutBoolean,
1388 rl_src[0], rl_src[1], vC);
1389 break;
1390 case Instruction::IPUT_BYTE:
1391 ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutByte,
1392 rl_src[0], rl_src[1], vC);
1393 break;
1394 case Instruction::IPUT_CHAR:
1395 ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutChar,
1396 rl_src[0], rl_src[1], vC);
1397 break;
1398 case Instruction::IPUT_SHORT:
1399 ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutShort,
1400 rl_src[0], rl_src[1], vC);
1401 break;
1402 case Instruction::IPUT_WIDE:
1403 if (rl_src[0].fp) {
1404 ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutDouble,
1405 rl_src[0], rl_src[1], vC);
1406 } else {
1407 ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutWide,
1408 rl_src[0], rl_src[1], vC);
1409 }
1410 break;
1411
1412 case Instruction::FILL_ARRAY_DATA:
1413 ConvertFillArrayData(vB, rl_src[0]);
1414 break;
1415
1416 case Instruction::LONG_TO_INT:
1417 ConvertLongToInt(rl_dest, rl_src[0]);
1418 break;
1419
1420 case Instruction::INT_TO_LONG:
1421 ConvertIntToLong(rl_dest, rl_src[0]);
1422 break;
1423
1424 case Instruction::INT_TO_CHAR:
1425 ConvertIntNarrowing(rl_dest, rl_src[0],
1426 art::llvm::IntrinsicHelper::IntToChar);
1427 break;
1428 case Instruction::INT_TO_BYTE:
1429 ConvertIntNarrowing(rl_dest, rl_src[0],
1430 art::llvm::IntrinsicHelper::IntToByte);
1431 break;
1432 case Instruction::INT_TO_SHORT:
1433 ConvertIntNarrowing(rl_dest, rl_src[0],
1434 art::llvm::IntrinsicHelper::IntToShort);
1435 break;
1436
1437 case Instruction::INT_TO_FLOAT:
1438 case Instruction::LONG_TO_FLOAT:
1439 ConvertIntToFP(irb_->getFloatTy(), rl_dest, rl_src[0]);
1440 break;
1441
1442 case Instruction::INT_TO_DOUBLE:
1443 case Instruction::LONG_TO_DOUBLE:
1444 ConvertIntToFP(irb_->getDoubleTy(), rl_dest, rl_src[0]);
1445 break;
1446
1447 case Instruction::FLOAT_TO_DOUBLE:
1448 ConvertFloatToDouble(rl_dest, rl_src[0]);
1449 break;
1450
1451 case Instruction::DOUBLE_TO_FLOAT:
1452 ConvertDoubleToFloat(rl_dest, rl_src[0]);
1453 break;
1454
1455 case Instruction::NEG_LONG:
1456 case Instruction::NEG_INT:
1457 ConvertNeg(rl_dest, rl_src[0]);
1458 break;
1459
1460 case Instruction::NEG_FLOAT:
1461 case Instruction::NEG_DOUBLE:
1462 ConvertNegFP(rl_dest, rl_src[0]);
1463 break;
1464
1465 case Instruction::NOT_LONG:
1466 case Instruction::NOT_INT:
1467 ConvertNot(rl_dest, rl_src[0]);
1468 break;
1469
1470 case Instruction::FLOAT_TO_INT:
1471 ConvertFPToInt(art::llvm::IntrinsicHelper::F2I, rl_dest, rl_src[0]);
1472 break;
1473
1474 case Instruction::DOUBLE_TO_INT:
1475 ConvertFPToInt(art::llvm::IntrinsicHelper::D2I, rl_dest, rl_src[0]);
1476 break;
1477
1478 case Instruction::FLOAT_TO_LONG:
1479 ConvertFPToInt(art::llvm::IntrinsicHelper::F2L, rl_dest, rl_src[0]);
1480 break;
1481
1482 case Instruction::DOUBLE_TO_LONG:
1483 ConvertFPToInt(art::llvm::IntrinsicHelper::D2L, rl_dest, rl_src[0]);
1484 break;
1485
1486 case Instruction::CMPL_FLOAT:
1487 ConvertWideComparison(art::llvm::IntrinsicHelper::CmplFloat,
1488 rl_dest, rl_src[0], rl_src[1]);
1489 break;
1490 case Instruction::CMPG_FLOAT:
1491 ConvertWideComparison(art::llvm::IntrinsicHelper::CmpgFloat,
1492 rl_dest, rl_src[0], rl_src[1]);
1493 break;
1494 case Instruction::CMPL_DOUBLE:
1495 ConvertWideComparison(art::llvm::IntrinsicHelper::CmplDouble,
1496 rl_dest, rl_src[0], rl_src[1]);
1497 break;
1498 case Instruction::CMPG_DOUBLE:
1499 ConvertWideComparison(art::llvm::IntrinsicHelper::CmpgDouble,
1500 rl_dest, rl_src[0], rl_src[1]);
1501 break;
1502 case Instruction::CMP_LONG:
1503 ConvertWideComparison(art::llvm::IntrinsicHelper::CmpLong,
1504 rl_dest, rl_src[0], rl_src[1]);
1505 break;
1506
1507 case Instruction::PACKED_SWITCH:
1508 ConvertPackedSwitch(bb, vB, rl_src[0]);
1509 break;
1510
1511 case Instruction::SPARSE_SWITCH:
1512 ConvertSparseSwitch(bb, vB, rl_src[0]);
1513 break;
1514
1515 default:
1516 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
1517 res = true;
1518 }
1519 return res;
Brian Carlstrom1895ea32013-07-18 13:28:37 -07001520} // NOLINT(readability/fn_size)
Brian Carlstrom7940e442013-07-12 13:46:57 -07001521
Brian Carlstrom2ce745c2013-07-17 17:44:30 -07001522void MirConverter::SetDexOffset(int32_t offset) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001523 current_dalvik_offset_ = offset;
1524 ::llvm::SmallVector< ::llvm::Value*, 1> array_ref;
1525 array_ref.push_back(irb_->getInt32(offset));
1526 ::llvm::MDNode* node = ::llvm::MDNode::get(*context_, array_ref);
1527 irb_->SetDexOffset(node);
1528}
1529
1530// Attach method info as metadata to special intrinsic
Brian Carlstrom2ce745c2013-07-17 17:44:30 -07001531void MirConverter::SetMethodInfo() {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001532 // We don't want dex offset on this
1533 irb_->SetDexOffset(NULL);
1534 art::llvm::IntrinsicHelper::IntrinsicId id;
1535 id = art::llvm::IntrinsicHelper::MethodInfo;
1536 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
1537 ::llvm::Instruction* inst = irb_->CreateCall(intr);
1538 ::llvm::SmallVector< ::llvm::Value*, 2> reg_info;
1539 reg_info.push_back(irb_->getInt32(cu_->num_ins));
1540 reg_info.push_back(irb_->getInt32(cu_->num_regs));
1541 reg_info.push_back(irb_->getInt32(cu_->num_outs));
Razvan A Lupusoruda7a69b2014-01-08 15:09:50 -08001542 reg_info.push_back(irb_->getInt32(mir_graph_->GetNumUsedCompilerTemps()));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001543 reg_info.push_back(irb_->getInt32(mir_graph_->GetNumSSARegs()));
1544 ::llvm::MDNode* reg_info_node = ::llvm::MDNode::get(*context_, reg_info);
1545 inst->setMetadata("RegInfo", reg_info_node);
1546 SetDexOffset(current_dalvik_offset_);
1547}
1548
Brian Carlstrom2ce745c2013-07-17 17:44:30 -07001549void MirConverter::HandlePhiNodes(BasicBlock* bb, ::llvm::BasicBlock* llvm_bb) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001550 SetDexOffset(bb->start_offset);
1551 for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
1552 int opcode = mir->dalvikInsn.opcode;
buzbee35ba7f32014-05-31 08:59:01 -07001553 if (!IsPseudoMirOp(opcode)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001554 // Stop after first non-pseudo MIR op.
1555 continue;
1556 }
1557 if (opcode != kMirOpPhi) {
1558 // Skip other mir Pseudos.
1559 continue;
1560 }
1561 RegLocation rl_dest = mir_graph_->reg_location_[mir->ssa_rep->defs[0]];
1562 /*
1563 * The Art compiler's Phi nodes only handle 32-bit operands,
1564 * representing wide values using a matched set of Phi nodes
1565 * for the lower and upper halves. In the llvm world, we only
1566 * want a single Phi for wides. Here we will simply discard
1567 * the Phi node representing the high word.
1568 */
1569 if (rl_dest.high_word) {
1570 continue; // No Phi node - handled via low word
1571 }
buzbee0d829482013-10-11 15:24:55 -07001572 BasicBlockId* incoming = mir->meta.phi_incoming;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001573 ::llvm::Type* phi_type =
1574 LlvmTypeFromLocRec(rl_dest);
1575 ::llvm::PHINode* phi = irb_->CreatePHI(phi_type, mir->ssa_rep->num_uses);
1576 for (int i = 0; i < mir->ssa_rep->num_uses; i++) {
1577 RegLocation loc;
1578 // Don't check width here.
1579 loc = mir_graph_->GetRawSrc(mir, i);
1580 DCHECK_EQ(rl_dest.wide, loc.wide);
1581 DCHECK_EQ(rl_dest.wide & rl_dest.high_word, loc.wide & loc.high_word);
1582 DCHECK_EQ(rl_dest.fp, loc.fp);
1583 DCHECK_EQ(rl_dest.core, loc.core);
1584 DCHECK_EQ(rl_dest.ref, loc.ref);
1585 SafeMap<unsigned int, unsigned int>::iterator it;
1586 it = mir_graph_->block_id_map_.find(incoming[i]);
1587 DCHECK(it != mir_graph_->block_id_map_.end());
1588 DCHECK(GetLLVMValue(loc.orig_sreg) != NULL);
1589 DCHECK(GetLLVMBlock(it->second) != NULL);
1590 phi->addIncoming(GetLLVMValue(loc.orig_sreg),
1591 GetLLVMBlock(it->second));
1592 }
1593 DefineValueOnly(phi, rl_dest.orig_sreg);
1594 }
1595}
1596
1597/* Extended MIR instructions like PHI */
1598void MirConverter::ConvertExtendedMIR(BasicBlock* bb, MIR* mir,
Brian Carlstrom0cd7ec22013-07-17 23:40:20 -07001599 ::llvm::BasicBlock* llvm_bb) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001600 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
1601 case kMirOpPhi: {
1602 // The llvm Phi node already emitted - just DefineValue() here.
1603 RegLocation rl_dest = mir_graph_->reg_location_[mir->ssa_rep->defs[0]];
1604 if (!rl_dest.high_word) {
1605 // Only consider low word of pairs.
1606 DCHECK(GetLLVMValue(rl_dest.orig_sreg) != NULL);
1607 ::llvm::Value* phi = GetLLVMValue(rl_dest.orig_sreg);
1608 if (1) SetVregOnValue(phi, rl_dest.orig_sreg);
1609 }
1610 break;
1611 }
1612 case kMirOpCopy: {
1613 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1614 break;
1615 }
1616 case kMirOpNop:
buzbee0d829482013-10-11 15:24:55 -07001617 if ((mir == bb->last_mir_insn) && (bb->taken == NullBasicBlockId) &&
1618 (bb->fall_through == NullBasicBlockId)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001619 irb_->CreateUnreachable();
1620 }
1621 break;
1622
1623 // TODO: need GBC intrinsic to take advantage of fused operations
1624 case kMirOpFusedCmplFloat:
1625 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
1626 break;
1627 case kMirOpFusedCmpgFloat:
1628 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
1629 break;
1630 case kMirOpFusedCmplDouble:
1631 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
1632 break;
1633 case kMirOpFusedCmpgDouble:
1634 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
1635 break;
1636 case kMirOpFusedCmpLong:
1637 UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
1638 break;
1639 default:
1640 break;
1641 }
1642}
1643
1644/* Handle the content in each basic block */
Brian Carlstrom2ce745c2013-07-17 17:44:30 -07001645bool MirConverter::BlockBitcodeConversion(BasicBlock* bb) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001646 if (bb->block_type == kDead) return false;
1647 ::llvm::BasicBlock* llvm_bb = GetLLVMBlock(bb->id);
1648 if (llvm_bb == NULL) {
1649 CHECK(bb->block_type == kExitBlock);
1650 } else {
1651 irb_->SetInsertPoint(llvm_bb);
1652 SetDexOffset(bb->start_offset);
1653 }
1654
1655 if (cu_->verbose) {
1656 LOG(INFO) << "................................";
1657 LOG(INFO) << "Block id " << bb->id;
1658 if (llvm_bb != NULL) {
1659 LOG(INFO) << "label " << llvm_bb->getName().str().c_str();
1660 } else {
1661 LOG(INFO) << "llvm_bb is NULL";
1662 }
1663 }
1664
1665 if (bb->block_type == kEntryBlock) {
1666 SetMethodInfo();
1667
Brian Carlstrom7934ac22013-07-26 10:54:15 -07001668 { // Allocate shadowframe.
Brian Carlstrom7940e442013-07-12 13:46:57 -07001669 art::llvm::IntrinsicHelper::IntrinsicId id =
1670 art::llvm::IntrinsicHelper::AllocaShadowFrame;
1671 ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(id);
1672 ::llvm::Value* entries = irb_->getInt32(cu_->num_dalvik_registers);
1673 irb_->CreateCall(func, entries);
1674 }
1675
Brian Carlstrom7934ac22013-07-26 10:54:15 -07001676 { // Store arguments to vregs.
Brian Carlstrom7940e442013-07-12 13:46:57 -07001677 uint16_t arg_reg = cu_->num_regs;
1678
1679 ::llvm::Function::arg_iterator arg_iter(func_->arg_begin());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001680
1681 const char* shorty = cu_->shorty;
1682 uint32_t shorty_size = strlen(shorty);
1683 CHECK_GE(shorty_size, 1u);
1684
Brian Carlstrom7934ac22013-07-26 10:54:15 -07001685 ++arg_iter; // skip method object
Brian Carlstrom7940e442013-07-12 13:46:57 -07001686
1687 if ((cu_->access_flags & kAccStatic) == 0) {
1688 SetVregOnValue(arg_iter, arg_reg);
1689 ++arg_iter;
1690 ++arg_reg;
1691 }
1692
1693 for (uint32_t i = 1; i < shorty_size; ++i, ++arg_iter) {
1694 SetVregOnValue(arg_iter, arg_reg);
1695
1696 ++arg_reg;
1697 if (shorty[i] == 'J' || shorty[i] == 'D') {
1698 // Wide types, such as long and double, are using a pair of registers
1699 // to store the value, so we have to increase arg_reg again.
1700 ++arg_reg;
1701 }
1702 }
1703 }
1704 } else if (bb->block_type == kExitBlock) {
1705 /*
1706 * Because of the differences between how MIR/LIR and llvm handle exit
1707 * blocks, we won't explicitly covert them. On the llvm-to-lir
1708 * path, it will need to be regenereated.
1709 */
1710 return false;
1711 } else if (bb->block_type == kExceptionHandling) {
1712 /*
1713 * Because we're deferring null checking, delete the associated empty
1714 * exception block.
1715 */
1716 llvm_bb->eraseFromParent();
1717 return false;
1718 }
1719
1720 HandlePhiNodes(bb, llvm_bb);
1721
1722 for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001723 SetDexOffset(mir->offset);
1724
1725 int opcode = mir->dalvikInsn.opcode;
1726 Instruction::Format dalvik_format =
1727 Instruction::FormatOf(mir->dalvikInsn.opcode);
1728
1729 if (opcode == kMirOpCheck) {
1730 // Combine check and work halves of throwing instruction.
1731 MIR* work_half = mir->meta.throw_insn;
1732 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
1733 opcode = mir->dalvikInsn.opcode;
1734 SSARepresentation* ssa_rep = work_half->ssa_rep;
1735 work_half->ssa_rep = mir->ssa_rep;
1736 mir->ssa_rep = ssa_rep;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001737 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
buzbee0d829482013-10-11 15:24:55 -07001738 if (bb->successor_block_list_type == kCatch) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001739 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(
1740 art::llvm::IntrinsicHelper::CatchTargets);
1741 ::llvm::Value* switch_key =
1742 irb_->CreateCall(intr, irb_->getInt32(mir->offset));
buzbee0d829482013-10-11 15:24:55 -07001743 GrowableArray<SuccessorBlockInfo*>::Iterator iter(bb->successor_blocks);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001744 // New basic block to use for work half
1745 ::llvm::BasicBlock* work_bb =
1746 ::llvm::BasicBlock::Create(*context_, "", func_);
1747 ::llvm::SwitchInst* sw =
buzbee0d829482013-10-11 15:24:55 -07001748 irb_->CreateSwitch(switch_key, work_bb, bb->successor_blocks->Size());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001749 while (true) {
1750 SuccessorBlockInfo *successor_block_info = iter.Next();
1751 if (successor_block_info == NULL) break;
1752 ::llvm::BasicBlock *target =
buzbee0d829482013-10-11 15:24:55 -07001753 GetLLVMBlock(successor_block_info->block);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001754 int type_index = successor_block_info->key;
1755 sw->addCase(irb_->getInt32(type_index), target);
1756 }
1757 llvm_bb = work_bb;
1758 irb_->SetInsertPoint(llvm_bb);
1759 }
1760 }
1761
buzbee35ba7f32014-05-31 08:59:01 -07001762 if (IsPseudoMirOp(opcode)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001763 ConvertExtendedMIR(bb, mir, llvm_bb);
1764 continue;
1765 }
1766
1767 bool not_handled = ConvertMIRNode(mir, bb, llvm_bb);
1768 if (not_handled) {
1769 Instruction::Code dalvik_opcode = static_cast<Instruction::Code>(opcode);
1770 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1771 mir->offset, opcode,
1772 Instruction::Name(dalvik_opcode),
1773 dalvik_format);
1774 }
1775 }
1776
1777 if (bb->block_type == kEntryBlock) {
buzbee0d829482013-10-11 15:24:55 -07001778 entry_target_bb_ = GetLLVMBlock(bb->fall_through);
1779 } else if ((bb->fall_through != NullBasicBlockId) && !bb->terminated_by_return) {
1780 irb_->CreateBr(GetLLVMBlock(bb->fall_through));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001781 }
1782
1783 return false;
1784}
1785
1786char RemapShorty(char shorty_type) {
1787 /*
1788 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1789 * and longs/doubles are represented as a pair of registers. When sub-word
1790 * arguments (and method results) are passed, they are extended to Dalvik
1791 * virtual register containers. Because llvm is picky about type consistency,
1792 * we must either cast the "real" type to 32-bit container multiple Dalvik
1793 * register types, or always use the expanded values.
1794 * Here, we're doing the latter. We map the shorty signature to container
1795 * types (which is valid so long as we always do a real expansion of passed
1796 * arguments and field loads).
1797 */
Brian Carlstromdf629502013-07-17 22:39:56 -07001798 switch (shorty_type) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001799 case 'Z' : shorty_type = 'I'; break;
1800 case 'B' : shorty_type = 'I'; break;
1801 case 'S' : shorty_type = 'I'; break;
1802 case 'C' : shorty_type = 'I'; break;
1803 default: break;
1804 }
1805 return shorty_type;
1806}
1807
1808::llvm::FunctionType* MirConverter::GetFunctionType() {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001809 // Get return type
1810 ::llvm::Type* ret_type = irb_->getJType(RemapShorty(cu_->shorty[0]));
1811
1812 // Get argument type
1813 std::vector< ::llvm::Type*> args_type;
1814
1815 // method object
1816 args_type.push_back(irb_->getJMethodTy());
1817
1818 // Do we have a "this"?
1819 if ((cu_->access_flags & kAccStatic) == 0) {
1820 args_type.push_back(irb_->getJObjectTy());
1821 }
1822
1823 for (uint32_t i = 1; i < strlen(cu_->shorty); ++i) {
1824 args_type.push_back(irb_->getJType(RemapShorty(cu_->shorty[i])));
1825 }
1826
1827 return ::llvm::FunctionType::get(ret_type, args_type, false);
1828}
1829
1830bool MirConverter::CreateFunction() {
1831 ::llvm::FunctionType* func_type = GetFunctionType();
1832 if (func_type == NULL) {
1833 return false;
1834 }
1835
1836 func_ = ::llvm::Function::Create(func_type,
1837 ::llvm::Function::InternalLinkage,
1838 symbol_, module_);
1839
1840 ::llvm::Function::arg_iterator arg_iter(func_->arg_begin());
1841 ::llvm::Function::arg_iterator arg_end(func_->arg_end());
1842
1843 arg_iter->setName("method");
1844 ++arg_iter;
1845
1846 int start_sreg = cu_->num_regs;
1847
1848 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1849 arg_iter->setName(StringPrintf("v%i_0", start_sreg));
1850 start_sreg += mir_graph_->reg_location_[start_sreg].wide ? 2 : 1;
1851 }
1852
1853 return true;
1854}
1855
Brian Carlstrom2ce745c2013-07-17 17:44:30 -07001856bool MirConverter::CreateLLVMBasicBlock(BasicBlock* bb) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001857 // Skip the exit block
1858 if ((bb->block_type == kDead) ||(bb->block_type == kExitBlock)) {
1859 id_to_block_map_.Put(bb->id, NULL);
1860 } else {
1861 int offset = bb->start_offset;
1862 bool entry_block = (bb->block_type == kEntryBlock);
1863 ::llvm::BasicBlock* llvm_bb =
1864 ::llvm::BasicBlock::Create(*context_, entry_block ? "entry" :
1865 StringPrintf(kLabelFormat, bb->catch_entry ? kCatchBlock :
1866 kNormalBlock, offset, bb->id), func_);
1867 if (entry_block) {
1868 entry_bb_ = llvm_bb;
1869 placeholder_bb_ =
1870 ::llvm::BasicBlock::Create(*context_, "placeholder",
1871 func_);
1872 }
1873 id_to_block_map_.Put(bb->id, llvm_bb);
1874 }
1875 return false;
1876}
1877
1878
1879/*
1880 * Convert MIR to LLVM_IR
1881 * o For each ssa name, create LLVM named value. Type these
1882 * appropriately, and ignore high half of wide and double operands.
1883 * o For each MIR basic block, create an LLVM basic block.
1884 * o Iterate through the MIR a basic block at a time, setting arguments
1885 * to recovered ssa name.
1886 */
Brian Carlstrom2ce745c2013-07-17 17:44:30 -07001887void MirConverter::MethodMIR2Bitcode() {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001888 InitIR();
1889
1890 // Create the function
1891 CreateFunction();
1892
1893 // Create an LLVM basic block for each MIR block in dfs preorder
buzbee56c71782013-09-05 17:13:19 -07001894 PreOrderDfsIterator iter(mir_graph_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001895 for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) {
1896 CreateLLVMBasicBlock(bb);
1897 }
1898
1899 /*
1900 * Create an llvm named value for each MIR SSA name. Note: we'll use
1901 * placeholders for all non-argument values (because we haven't seen
1902 * the definition yet).
1903 */
1904 irb_->SetInsertPoint(placeholder_bb_);
1905 ::llvm::Function::arg_iterator arg_iter(func_->arg_begin());
1906 arg_iter++; /* Skip path method */
1907 for (int i = 0; i < mir_graph_->GetNumSSARegs(); i++) {
1908 ::llvm::Value* val;
1909 RegLocation rl_temp = mir_graph_->reg_location_[i];
1910 if ((mir_graph_->SRegToVReg(i) < 0) || rl_temp.high_word) {
1911 llvm_values_.Insert(0);
1912 } else if ((i < cu_->num_regs) ||
1913 (i >= (cu_->num_regs + cu_->num_ins))) {
1914 ::llvm::Constant* imm_value = mir_graph_->reg_location_[i].wide ?
1915 irb_->getJLong(0) : irb_->getJInt(0);
1916 val = EmitConst(imm_value, mir_graph_->reg_location_[i]);
1917 val->setName(mir_graph_->GetSSAName(i));
1918 llvm_values_.Insert(val);
1919 } else {
1920 // Recover previously-created argument values
1921 ::llvm::Value* arg_val = arg_iter++;
1922 llvm_values_.Insert(arg_val);
1923 }
1924 }
1925
buzbee56c71782013-09-05 17:13:19 -07001926 PreOrderDfsIterator iter2(mir_graph_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001927 for (BasicBlock* bb = iter2.Next(); bb != NULL; bb = iter2.Next()) {
1928 BlockBitcodeConversion(bb);
1929 }
1930
1931 /*
1932 * In a few rare cases of verification failure, the verifier will
1933 * replace one or more Dalvik opcodes with the special
1934 * throw-verification-failure opcode. This can leave the SSA graph
1935 * in an invalid state, as definitions may be lost, while uses retained.
1936 * To work around this problem, we insert placeholder definitions for
1937 * all Dalvik SSA regs in the "placeholder" block. Here, after
1938 * bitcode conversion is complete, we examine those placeholder definitions
1939 * and delete any with no references (which normally is all of them).
1940 *
1941 * If any definitions remain, we link the placeholder block into the
1942 * CFG. Otherwise, it is deleted.
1943 */
1944 for (::llvm::BasicBlock::iterator it = placeholder_bb_->begin(),
1945 it_end = placeholder_bb_->end(); it != it_end;) {
1946 ::llvm::Instruction* inst = ::llvm::dyn_cast< ::llvm::Instruction>(it++);
1947 DCHECK(inst != NULL);
1948 ::llvm::Value* val = ::llvm::dyn_cast< ::llvm::Value>(inst);
1949 DCHECK(val != NULL);
1950 if (val->getNumUses() == 0) {
1951 inst->eraseFromParent();
1952 }
1953 }
1954 SetDexOffset(0);
1955 if (placeholder_bb_->empty()) {
1956 placeholder_bb_->eraseFromParent();
1957 } else {
1958 irb_->SetInsertPoint(placeholder_bb_);
1959 irb_->CreateBr(entry_target_bb_);
1960 entry_target_bb_ = placeholder_bb_;
1961 }
1962 irb_->SetInsertPoint(entry_bb_);
1963 irb_->CreateBr(entry_target_bb_);
1964
1965 if (cu_->enable_debug & (1 << kDebugVerifyBitcode)) {
1966 if (::llvm::verifyFunction(*func_, ::llvm::PrintMessageAction)) {
1967 LOG(INFO) << "Bitcode verification FAILED for "
1968 << PrettyMethod(cu_->method_idx, *cu_->dex_file)
1969 << " of size " << cu_->code_item->insns_size_in_code_units_;
1970 cu_->enable_debug |= (1 << kDebugDumpBitcodeFile);
1971 }
1972 }
1973
1974 if (cu_->enable_debug & (1 << kDebugDumpBitcodeFile)) {
1975 // Write bitcode to file
1976 std::string errmsg;
1977 std::string fname(PrettyMethod(cu_->method_idx, *cu_->dex_file));
1978 mir_graph_->ReplaceSpecialChars(fname);
1979 // TODO: make configurable change naming mechanism to avoid fname length issues.
1980 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
1981
1982 if (fname.size() > 240) {
1983 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
1984 fname.resize(240);
1985 }
1986
1987 ::llvm::OwningPtr< ::llvm::tool_output_file> out_file(
1988 new ::llvm::tool_output_file(fname.c_str(), errmsg,
Stephen Hines73fbaad2013-08-09 02:14:36 -07001989 ::llvm::sys::fs::F_Binary));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001990
1991 if (!errmsg.empty()) {
1992 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1993 }
1994
1995 ::llvm::WriteBitcodeToFile(module_, out_file->os());
1996 out_file->keep();
1997 }
1998}
1999
2000Backend* PortableCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph,
2001 ArenaAllocator* const arena,
2002 llvm::LlvmCompilationUnit* const llvm_compilation_unit) {
2003 return new MirConverter(cu, mir_graph, arena, llvm_compilation_unit);
2004}
2005
2006} // namespace art