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 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 59 LLVMInfo::~LLVMInfo() { 60 } 61 62 ::llvm::BasicBlock* MirConverter::GetLLVMBlock(int id) { 63 return id_to_block_map_.Get(id); 64 } 65 66 ::llvm::Value* MirConverter::GetLLVMValue(int s_reg) { 67 return llvm_values_.Get(s_reg); 68 } 69 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 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 96 void MirConverter::DefineValue(::llvm::Value* val, int s_reg) { 97 DefineValueOnly(val, s_reg); 98 SetVregOnValue(val, s_reg); 99 } 100 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 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 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 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 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 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 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 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 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 243 void MirConverter::EmitPopShadowFrame() { 244 ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction( 245 art::llvm::IntrinsicHelper::PopShadowFrame); 246 irb_->CreateCall(intr); 247 } 248 249 ::llvm::Value* MirConverter::EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src, 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 */ 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 */ 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 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 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 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 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 */ 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 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