1 /*
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"
33 #include "llvm/ir_builder.h"
34 #include "llvm/llvm_compilation_unit.h"
35 #include "llvm/utils_llvm.h"
36 #include "mir_to_gbc.h"
37 #include "thread-inl.h"
38
39 const char* kLabelFormat = "%c0x%x_%d";
40 const char kInvalidBlock = 0xff;
41 const char kNormalBlock = 'L';
42 const char kCatchBlock = 'C';
43
44 namespace art {
45 namespace llvm {
46 ::llvm::Module* makeLLVMModuleContents(::llvm::Module* module);
47 }
48
LLVMInfo()49 LLVMInfo::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
~LLVMInfo()59 LLVMInfo::~LLVMInfo() {
60 }
61
GetLLVMBlock(int id)62 ::llvm::BasicBlock* MirConverter::GetLLVMBlock(int id) {
63 return id_to_block_map_.Get(id);
64 }
65
GetLLVMValue(int s_reg)66 ::llvm::Value* MirConverter::GetLLVMValue(int s_reg) {
67 return llvm_values_.Get(s_reg);
68 }
69
SetVregOnValue(::llvm::Value * val,int s_reg)70 void MirConverter::SetVregOnValue(::llvm::Value* val, int s_reg) {
71 // 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
DefineValueOnly(::llvm::Value * val,int s_reg)81 void MirConverter::DefineValueOnly(::llvm::Value* val, int s_reg) {
82 ::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();
94 }
95
DefineValue(::llvm::Value * val,int s_reg)96 void MirConverter::DefineValue(::llvm::Value* val, int s_reg) {
97 DefineValueOnly(val, s_reg);
98 SetVregOnValue(val, s_reg);
99 }
100
LlvmTypeFromLocRec(RegLocation loc)101 ::llvm::Type* MirConverter::LlvmTypeFromLocRec(RegLocation loc) {
102 ::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
InitIR()121 void MirConverter::InitIR() {
122 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
FindCaseTarget(uint32_t vaddr)137 ::llvm::BasicBlock* MirConverter::FindCaseTarget(uint32_t vaddr) {
138 BasicBlock* bb = mir_graph_->FindBlock(vaddr);
139 DCHECK(bb != NULL);
140 return GetLLVMBlock(bb->id);
141 }
142
ConvertPackedSwitch(BasicBlock * bb,int32_t table_offset,RegLocation rl_src)143 void MirConverter::ConvertPackedSwitch(BasicBlock* bb,
144 int32_t table_offset, RegLocation rl_src) {
145 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 =
152 irb_->CreateSwitch(value, GetLLVMBlock(bb->fall_through),
153 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);
163 bb->taken = NullBasicBlockId;
164 bb->fall_through = NullBasicBlockId;
165 }
166
ConvertSparseSwitch(BasicBlock * bb,int32_t table_offset,RegLocation rl_src)167 void MirConverter::ConvertSparseSwitch(BasicBlock* bb,
168 int32_t table_offset, RegLocation rl_src) {
169 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 =
179 irb_->CreateSwitch(value, GetLLVMBlock(bb->fall_through),
180 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);
190 bb->taken = NullBasicBlockId;
191 bb->fall_through = NullBasicBlockId;
192 }
193
ConvertSget(int32_t field_index,art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_dest)194 void MirConverter::ConvertSget(int32_t field_index,
195 art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest) {
196 ::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
ConvertSput(int32_t field_index,art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_src)202 void MirConverter::ConvertSput(int32_t field_index,
203 art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src) {
204 ::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
ConvertFillArrayData(int32_t offset,RegLocation rl_array)211 void MirConverter::ConvertFillArrayData(int32_t offset, RegLocation rl_array) {
212 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
EmitConst(::llvm::ArrayRef<::llvm::Value * > src,RegLocation loc)221 ::llvm::Value* MirConverter::EmitConst(::llvm::ArrayRef< ::llvm::Value*> src,
222 RegLocation loc) {
223 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
EmitPopShadowFrame()243 void MirConverter::EmitPopShadowFrame() {
244 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(
245 art::llvm::IntrinsicHelper::PopShadowFrame);
246 irb_->CreateCall(intr);
247 }
248
EmitCopy(::llvm::ArrayRef<::llvm::Value * > src,RegLocation loc)249 ::llvm::Value* MirConverter::EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src,
250 RegLocation loc) {
251 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
ConvertMoveException(RegLocation rl_dest)271 void MirConverter::ConvertMoveException(RegLocation rl_dest) {
272 ::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
ConvertThrow(RegLocation rl_src)278 void MirConverter::ConvertThrow(RegLocation rl_src) {
279 ::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
ConvertMonitorEnterExit(int opt_flags,art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_src)285 void MirConverter::ConvertMonitorEnterExit(int opt_flags,
286 art::llvm::IntrinsicHelper::IntrinsicId id,
287 RegLocation rl_src) {
288 ::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
ConvertArrayLength(int opt_flags,RegLocation rl_dest,RegLocation rl_src)295 void MirConverter::ConvertArrayLength(int opt_flags,
296 RegLocation rl_dest, RegLocation rl_src) {
297 ::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
EmitSuspendCheck()306 void MirConverter::EmitSuspendCheck() {
307 art::llvm::IntrinsicHelper::IntrinsicId id =
308 art::llvm::IntrinsicHelper::CheckSuspend;
309 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
310 irb_->CreateCall(intr);
311 }
312
ConvertCompare(ConditionCode cc,::llvm::Value * src1,::llvm::Value * src2)313 ::llvm::Value* MirConverter::ConvertCompare(ConditionCode cc,
314 ::llvm::Value* src1, ::llvm::Value* src2) {
315 ::llvm::Value* res = NULL;
316 DCHECK_EQ(src1->getType(), src2->getType());
317 switch (cc) {
318 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
ConvertCompareAndBranch(BasicBlock * bb,MIR * mir,ConditionCode cc,RegLocation rl_src1,RegLocation rl_src2)329 void MirConverter::ConvertCompareAndBranch(BasicBlock* bb, MIR* mir,
330 ConditionCode cc, RegLocation rl_src1, RegLocation rl_src2) {
331 if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= mir->offset) {
332 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_++));
338 irb_->CreateCondBr(cond_value, GetLLVMBlock(bb->taken),
339 GetLLVMBlock(bb->fall_through));
340 // Don't redo the fallthrough branch in the BB driver
341 bb->fall_through = NullBasicBlockId;
342 }
343
ConvertCompareZeroAndBranch(BasicBlock * bb,MIR * mir,ConditionCode cc,RegLocation rl_src1)344 void MirConverter::ConvertCompareZeroAndBranch(BasicBlock* bb,
345 MIR* mir, ConditionCode cc, RegLocation rl_src1) {
346 if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= mir->offset) {
347 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);
357 irb_->CreateCondBr(cond_value, GetLLVMBlock(bb->taken),
358 GetLLVMBlock(bb->fall_through));
359 // Don't redo the fallthrough branch in the BB driver
360 bb->fall_through = NullBasicBlockId;
361 }
362
GenDivModOp(bool is_div,bool is_long,::llvm::Value * src1,::llvm::Value * src2)363 ::llvm::Value* MirConverter::GenDivModOp(bool is_div, bool is_long,
364 ::llvm::Value* src1, ::llvm::Value* src2) {
365 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
GenArithOp(OpKind op,bool is_long,::llvm::Value * src1,::llvm::Value * src2)386 ::llvm::Value* MirConverter::GenArithOp(OpKind op, bool is_long,
387 ::llvm::Value* src1, ::llvm::Value* src2) {
388 ::llvm::Value* res = NULL;
389 switch (op) {
390 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
ConvertFPArithOp(OpKind op,RegLocation rl_dest,RegLocation rl_src1,RegLocation rl_src2)408 void MirConverter::ConvertFPArithOp(OpKind op, RegLocation rl_dest,
409 RegLocation rl_src1, RegLocation rl_src2) {
410 ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
411 ::llvm::Value* src2 = GetLLVMValue(rl_src2.orig_sreg);
412 ::llvm::Value* res = NULL;
413 switch (op) {
414 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
ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_dest,RegLocation rl_src1,RegLocation rl_src2)425 void MirConverter::ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id,
426 RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) {
427 ::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
ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_dest,RegLocation rl_src,int shift_amount)435 void MirConverter::ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id,
436 RegLocation rl_dest, RegLocation rl_src, int shift_amount) {
437 ::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
ConvertArithOp(OpKind op,RegLocation rl_dest,RegLocation rl_src1,RegLocation rl_src2)445 void MirConverter::ConvertArithOp(OpKind op, RegLocation rl_dest,
446 RegLocation rl_src1, RegLocation rl_src2) {
447 ::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
ConvertArithOpLit(OpKind op,RegLocation rl_dest,RegLocation rl_src1,int32_t imm)454 void MirConverter::ConvertArithOpLit(OpKind op, RegLocation rl_dest,
455 RegLocation rl_src1, int32_t imm) {
456 ::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 */
ConvertInvoke(BasicBlock * bb,MIR * mir,InvokeType invoke_type,bool is_range,bool is_filled_new_array)467 void MirConverter::ConvertInvoke(BasicBlock* bb, MIR* mir,
468 InvokeType invoke_type, bool is_range, bool is_filled_new_array) {
469 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
ConvertConstObject(uint32_t idx,art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_dest)515 void MirConverter::ConvertConstObject(uint32_t idx,
516 art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest) {
517 ::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
ConvertCheckCast(uint32_t type_idx,RegLocation rl_src)523 void MirConverter::ConvertCheckCast(uint32_t type_idx, RegLocation rl_src) {
524 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
ConvertNewInstance(uint32_t type_idx,RegLocation rl_dest)533 void MirConverter::ConvertNewInstance(uint32_t type_idx, RegLocation rl_dest) {
534 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
ConvertNewArray(uint32_t type_idx,RegLocation rl_dest,RegLocation rl_src)542 void MirConverter::ConvertNewArray(uint32_t type_idx,
543 RegLocation rl_dest, RegLocation rl_src) {
544 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
ConvertAget(int opt_flags,art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_dest,RegLocation rl_array,RegLocation rl_index)554 void MirConverter::ConvertAget(int opt_flags,
555 art::llvm::IntrinsicHelper::IntrinsicId id,
556 RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index) {
557 ::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
ConvertAput(int opt_flags,art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_src,RegLocation rl_array,RegLocation rl_index)566 void MirConverter::ConvertAput(int opt_flags,
567 art::llvm::IntrinsicHelper::IntrinsicId id,
568 RegLocation rl_src, RegLocation rl_array, RegLocation rl_index) {
569 ::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
ConvertIget(int opt_flags,art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_dest,RegLocation rl_obj,int field_index)578 void MirConverter::ConvertIget(int opt_flags,
579 art::llvm::IntrinsicHelper::IntrinsicId id,
580 RegLocation rl_dest, RegLocation rl_obj, int field_index) {
581 ::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
ConvertIput(int opt_flags,art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_src,RegLocation rl_obj,int field_index)590 void MirConverter::ConvertIput(int opt_flags,
591 art::llvm::IntrinsicHelper::IntrinsicId id,
592 RegLocation rl_src, RegLocation rl_obj, int field_index) {
593 ::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
ConvertInstanceOf(uint32_t type_idx,RegLocation rl_dest,RegLocation rl_src)602 void MirConverter::ConvertInstanceOf(uint32_t type_idx,
603 RegLocation rl_dest, RegLocation rl_src) {
604 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
ConvertIntToLong(RegLocation rl_dest,RegLocation rl_src)614 void MirConverter::ConvertIntToLong(RegLocation rl_dest, RegLocation rl_src) {
615 ::llvm::Value* res = irb_->CreateSExt(GetLLVMValue(rl_src.orig_sreg),
616 irb_->getInt64Ty());
617 DefineValue(res, rl_dest.orig_sreg);
618 }
619
ConvertLongToInt(RegLocation rl_dest,RegLocation rl_src)620 void MirConverter::ConvertLongToInt(RegLocation rl_dest, RegLocation rl_src) {
621 ::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
ConvertFloatToDouble(RegLocation rl_dest,RegLocation rl_src)626 void MirConverter::ConvertFloatToDouble(RegLocation rl_dest, RegLocation rl_src) {
627 ::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
ConvertDoubleToFloat(RegLocation rl_dest,RegLocation rl_src)632 void MirConverter::ConvertDoubleToFloat(RegLocation rl_dest, RegLocation rl_src) {
633 ::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
ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_dest,RegLocation rl_src1,RegLocation rl_src2)638 void MirConverter::ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id,
639 RegLocation rl_dest, RegLocation rl_src1,
640 RegLocation rl_src2) {
641 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
ConvertIntNarrowing(RegLocation rl_dest,RegLocation rl_src,art::llvm::IntrinsicHelper::IntrinsicId id)651 void MirConverter::ConvertIntNarrowing(RegLocation rl_dest, RegLocation rl_src,
652 art::llvm::IntrinsicHelper::IntrinsicId id) {
653 ::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
ConvertNeg(RegLocation rl_dest,RegLocation rl_src)659 void MirConverter::ConvertNeg(RegLocation rl_dest, RegLocation rl_src) {
660 ::llvm::Value* res = irb_->CreateNeg(GetLLVMValue(rl_src.orig_sreg));
661 DefineValue(res, rl_dest.orig_sreg);
662 }
663
ConvertIntToFP(::llvm::Type * ty,RegLocation rl_dest,RegLocation rl_src)664 void MirConverter::ConvertIntToFP(::llvm::Type* ty, RegLocation rl_dest,
665 RegLocation rl_src) {
666 ::llvm::Value* res =
667 irb_->CreateSIToFP(GetLLVMValue(rl_src.orig_sreg), ty);
668 DefineValue(res, rl_dest.orig_sreg);
669 }
670
ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id,RegLocation rl_dest,RegLocation rl_src)671 void MirConverter::ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id,
672 RegLocation rl_dest,
673 RegLocation rl_src) {
674 ::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
ConvertNegFP(RegLocation rl_dest,RegLocation rl_src)680 void MirConverter::ConvertNegFP(RegLocation rl_dest, RegLocation rl_src) {
681 ::llvm::Value* res =
682 irb_->CreateFNeg(GetLLVMValue(rl_src.orig_sreg));
683 DefineValue(res, rl_dest.orig_sreg);
684 }
685
ConvertNot(RegLocation rl_dest,RegLocation rl_src)686 void MirConverter::ConvertNot(RegLocation rl_dest, RegLocation rl_src) {
687 ::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
EmitConstructorBarrier()692 void 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 */
ConvertMIRNode(MIR * mir,BasicBlock * bb,::llvm::BasicBlock * llvm_bb)703 bool MirConverter::ConvertMIRNode(MIR* mir, BasicBlock* bb,
704 ::llvm::BasicBlock* llvm_bb) {
705 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) {
715 if (!IsPseudoMirOp(op_val)) {
716 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;
725 uint64_t attrs = MirGraph::GetDataFlowAttributes(opcode);
726 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: {
961 if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= bb->start_offset) {
962 EmitSuspendCheck();
963 }
964 irb_->CreateBr(GetLLVMBlock(bb->taken));
965 }
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
1199 case Instruction::MOVE_EXCEPTION:
1200 ConvertMoveException(rl_dest);
1201 break;
1202
1203 case Instruction::THROW:
1204 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 */
1210 if (bb->fall_through == NullBasicBlockId) {
1211 irb_->CreateUnreachable();
1212 } else {
1213 mir_graph_->GetBasicBlock(bb->fall_through)->fall_through = NullBasicBlockId;
1214 mir_graph_->GetBasicBlock(bb->fall_through)->taken = NullBasicBlockId;
1215 }
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;
1520 } // NOLINT(readability/fn_size)
1521
SetDexOffset(int32_t offset)1522 void MirConverter::SetDexOffset(int32_t offset) {
1523 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
SetMethodInfo()1531 void MirConverter::SetMethodInfo() {
1532 // 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));
1542 reg_info.push_back(irb_->getInt32(mir_graph_->GetNumUsedCompilerTemps()));
1543 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
HandlePhiNodes(BasicBlock * bb,::llvm::BasicBlock * llvm_bb)1549 void MirConverter::HandlePhiNodes(BasicBlock* bb, ::llvm::BasicBlock* llvm_bb) {
1550 SetDexOffset(bb->start_offset);
1551 for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
1552 int opcode = mir->dalvikInsn.opcode;
1553 if (!IsPseudoMirOp(opcode)) {
1554 // 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 }
1572 BasicBlockId* incoming = mir->meta.phi_incoming;
1573 ::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 */
ConvertExtendedMIR(BasicBlock * bb,MIR * mir,::llvm::BasicBlock * llvm_bb)1598 void MirConverter::ConvertExtendedMIR(BasicBlock* bb, MIR* mir,
1599 ::llvm::BasicBlock* llvm_bb) {
1600 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:
1617 if ((mir == bb->last_mir_insn) && (bb->taken == NullBasicBlockId) &&
1618 (bb->fall_through == NullBasicBlockId)) {
1619 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 */
BlockBitcodeConversion(BasicBlock * bb)1645 bool MirConverter::BlockBitcodeConversion(BasicBlock* bb) {
1646 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
1668 { // Allocate shadowframe.
1669 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
1676 { // Store arguments to vregs.
1677 uint16_t arg_reg = cu_->num_regs;
1678
1679 ::llvm::Function::arg_iterator arg_iter(func_->arg_begin());
1680
1681 const char* shorty = cu_->shorty;
1682 uint32_t shorty_size = strlen(shorty);
1683 CHECK_GE(shorty_size, 1u);
1684
1685 ++arg_iter; // skip method object
1686
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) {
1723 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;
1737 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1738 if (bb->successor_block_list_type == kCatch) {
1739 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(
1740 art::llvm::IntrinsicHelper::CatchTargets);
1741 ::llvm::Value* switch_key =
1742 irb_->CreateCall(intr, irb_->getInt32(mir->offset));
1743 GrowableArray<SuccessorBlockInfo*>::Iterator iter(bb->successor_blocks);
1744 // New basic block to use for work half
1745 ::llvm::BasicBlock* work_bb =
1746 ::llvm::BasicBlock::Create(*context_, "", func_);
1747 ::llvm::SwitchInst* sw =
1748 irb_->CreateSwitch(switch_key, work_bb, bb->successor_blocks->Size());
1749 while (true) {
1750 SuccessorBlockInfo *successor_block_info = iter.Next();
1751 if (successor_block_info == NULL) break;
1752 ::llvm::BasicBlock *target =
1753 GetLLVMBlock(successor_block_info->block);
1754 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
1762 if (IsPseudoMirOp(opcode)) {
1763 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) {
1778 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));
1781 }
1782
1783 return false;
1784 }
1785
RemapShorty(char shorty_type)1786 char 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 */
1798 switch (shorty_type) {
1799 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
GetFunctionType()1808 ::llvm::FunctionType* MirConverter::GetFunctionType() {
1809 // 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
CreateFunction()1830 bool 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
CreateLLVMBasicBlock(BasicBlock * bb)1856 bool MirConverter::CreateLLVMBasicBlock(BasicBlock* bb) {
1857 // 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 */
MethodMIR2Bitcode()1887 void MirConverter::MethodMIR2Bitcode() {
1888 InitIR();
1889
1890 // Create the function
1891 CreateFunction();
1892
1893 // Create an LLVM basic block for each MIR block in dfs preorder
1894 PreOrderDfsIterator iter(mir_graph_);
1895 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
1926 PreOrderDfsIterator iter2(mir_graph_);
1927 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,
1989 ::llvm::sys::fs::F_Binary));
1990
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
PortableCodeGenerator(CompilationUnit * const cu,MIRGraph * const mir_graph,ArenaAllocator * const arena,llvm::LlvmCompilationUnit * const llvm_compilation_unit)2000 Backend* 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
2007