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