blob: 27e7d261eef9ab87222265421da0653222a103a4 [file] [log] [blame]
buzbee2cfc6392012-05-07 14:51:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#if defined(ART_USE_QUICK_COMPILER)
18
19#include "object_utils.h"
20
21#include <llvm/Support/ToolOutputFile.h>
22#include <llvm/Bitcode/ReaderWriter.h>
23#include <llvm/Analysis/Verifier.h>
24#include <llvm/Metadata.h>
25#include <llvm/ADT/DepthFirstIterator.h>
26#include <llvm/Instruction.h>
27#include <llvm/Type.h>
28#include <llvm/Instructions.h>
29#include <llvm/Support/Casting.h>
30
31const char* labelFormat = "L0x%x_d";
32
33namespace art {
34extern const RegLocation badLoc;
35
36llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
37{
38 return cUnit->idToBlockMap.Get(id);
39}
40
41llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
42{
43 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
44}
45
46// Replace the placeholder value with the real definition
47void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
48{
49 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
50 CHECK(placeholder != NULL) << "Null placeholder - shouldn't happen";
51 placeholder->replaceAllUsesWith(val);
52 val->takeName(placeholder);
53 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
54}
55
56llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
57{
58 llvm::Type* res = NULL;
59 if (loc.wide) {
60 if (loc.fp)
61 res = cUnit->irb->GetJDoubleTy();
62 else
63 res = cUnit->irb->GetJLongTy();
64 } else {
65 if (loc.fp) {
66 res = cUnit->irb->GetJFloatTy();
67 } else {
68 if (loc.ref)
69 res = cUnit->irb->GetJObjectTy();
70 else
71 res = cUnit->irb->GetJIntTy();
72 }
73 }
74 return res;
75}
76
77void initIR(CompilationUnit* cUnit)
78{
79 cUnit->context = new llvm::LLVMContext();
80 cUnit->module = new llvm::Module("art", *cUnit->context);
81 llvm::StructType::create(*cUnit->context, "JavaObject");
82 llvm::StructType::create(*cUnit->context, "Method");
83 llvm::StructType::create(*cUnit->context, "Thread");
84 cUnit->intrinsic_helper =
85 new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
86 cUnit->irb =
87 new greenland::IRBuilder(*cUnit->context, *cUnit->module,
88 *cUnit->intrinsic_helper);
89}
90
91void freeIR(CompilationUnit* cUnit)
92{
93 delete cUnit->irb;
94 delete cUnit->intrinsic_helper;
95 delete cUnit->module;
96 delete cUnit->context;
97}
98
99const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
100 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
101}
102
103llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
104 RegLocation loc)
105{
106 greenland::IntrinsicHelper::IntrinsicId id;
107 if (loc.wide) {
108 if (loc.fp) {
109 id = greenland::IntrinsicHelper::ConstDouble;
110 } else {
111 id = greenland::IntrinsicHelper::ConstLong;
112 }
113 } else {
114 if (loc.fp) {
115 id = greenland::IntrinsicHelper::ConstFloat;
116 } if (loc.ref) {
117 id = greenland::IntrinsicHelper::ConstObj;
118 } else {
119 id = greenland::IntrinsicHelper::ConstInt;
120 }
121 }
122 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
123 return cUnit->irb->CreateCall(intr, src);
124}
125llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
126 RegLocation loc)
127{
128 greenland::IntrinsicHelper::IntrinsicId id;
129 if (loc.wide) {
130 if (loc.fp) {
131 id = greenland::IntrinsicHelper::CopyDouble;
132 } else {
133 id = greenland::IntrinsicHelper::CopyLong;
134 }
135 } else {
136 if (loc.fp) {
137 id = greenland::IntrinsicHelper::CopyFloat;
138 } if (loc.ref) {
139 id = greenland::IntrinsicHelper::CopyObj;
140 } else {
141 id = greenland::IntrinsicHelper::CopyInt;
142 }
143 }
144 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
145 return cUnit->irb->CreateCall(intr, src);
146}
147
148void emitSuspendCheck(CompilationUnit* cUnit)
149{
150 greenland::IntrinsicHelper::IntrinsicId id =
151 greenland::IntrinsicHelper::CheckSuspend;
152 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
153 cUnit->irb->CreateCall(intr);
154}
155
156llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
157 llvm::Value* src1, llvm::Value* src2)
158{
159 llvm::Value* res = NULL;
160 switch(cc) {
161 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
162 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
163 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
164 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
165 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
166 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
167 default: LOG(FATAL) << "Unexpected cc value " << cc;
168 }
169 return res;
170}
171
172void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
173 ConditionCode cc, RegLocation rlSrc1,
174 RegLocation rlSrc2)
175{
176 if (bb->taken->startOffset <= mir->offset) {
177 emitSuspendCheck(cUnit);
178 }
179 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
180 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
181 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
182 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
183 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
184 getLLVMBlock(cUnit, bb->fallThrough->id));
185}
186
187void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
188 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
189{
190 if (bb->taken->startOffset <= mir->offset) {
191 emitSuspendCheck(cUnit);
192 }
193 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
194 llvm::Value* src2;
195 if (rlSrc1.ref) {
196 src2 = cUnit->irb->GetJNull();
197 } else {
198 src2 = cUnit->irb->getInt32(0);
199 }
200 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
201 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
202 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
203 getLLVMBlock(cUnit, bb->fallThrough->id));
204}
205
206llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
207 llvm::Value* src1, llvm::Value* src2)
208{
209 greenland::IntrinsicHelper::IntrinsicId id;
210 if (isLong) {
211 if (isDiv) {
212 id = greenland::IntrinsicHelper::DivLong;
213 } else {
214 id = greenland::IntrinsicHelper::RemLong;
215 }
216 } else if (isDiv) {
217 id = greenland::IntrinsicHelper::DivInt;
218 } else {
219 id = greenland::IntrinsicHelper::RemInt;
220 }
221 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
222 llvm::SmallVector<llvm::Value*, 2>args;
223 args.push_back(src1);
224 args.push_back(src2);
225 return cUnit->irb->CreateCall(intr, args);
226}
227
228llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
229 llvm::Value* src1, llvm::Value* src2)
230{
231 llvm::Value* res = NULL;
232 switch(op) {
233 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
234 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
235 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
236 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
237 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
238 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
239 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
240 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
241 case kOpLsl: UNIMPLEMENTED(FATAL) << "Need Lsl"; break;
242 case kOpLsr: UNIMPLEMENTED(FATAL) << "Need Lsr"; break;
243 case kOpAsr: UNIMPLEMENTED(FATAL) << "Need Asr"; break;
244 default:
245 LOG(FATAL) << "Invalid op " << op;
246 }
247 return res;
248}
249
250void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
251 RegLocation rlSrc1, RegLocation rlSrc2)
252{
253 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
254 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
255 llvm::Value* res = NULL;
256 switch(op) {
257 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
258 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
259 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
260 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
261 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
262 default:
263 LOG(FATAL) << "Invalid op " << op;
264 }
265 defineValue(cUnit, res, rlDest.origSReg);
266}
267
268void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
269 RegLocation rlSrc1, RegLocation rlSrc2)
270{
271 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
272 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
273 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
274 defineValue(cUnit, res, rlDest.origSReg);
275}
276
277void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
278 RegLocation rlSrc1, int32_t imm)
279{
280 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
281 llvm::Value* src2 = cUnit->irb->getInt32(imm);
282 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
283 defineValue(cUnit, res, rlDest.origSReg);
284}
285
286/*
287 * Target-independent code generation. Use only high-level
288 * load/store utilities here, or target-dependent genXX() handlers
289 * when necessary.
290 */
291bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
292 llvm::BasicBlock* llvmBB, LIR* labelList)
293{
294 bool res = false; // Assume success
295 RegLocation rlSrc[3];
296 RegLocation rlDest = badLoc;
297 RegLocation rlResult = badLoc;
298 Instruction::Code opcode = mir->dalvikInsn.opcode;
299
300 /* Prep Src and Dest locations */
301 int nextSreg = 0;
302 int nextLoc = 0;
303 int attrs = oatDataFlowAttributes[opcode];
304 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
305 if (attrs & DF_UA) {
306 if (attrs & DF_A_WIDE) {
307 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg, nextSreg + 1);
308 nextSreg+= 2;
309 } else {
310 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
311 nextSreg++;
312 }
313 }
314 if (attrs & DF_UB) {
315 if (attrs & DF_B_WIDE) {
316 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg, nextSreg + 1);
317 nextSreg+= 2;
318 } else {
319 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
320 nextSreg++;
321 }
322 }
323 if (attrs & DF_UC) {
324 if (attrs & DF_C_WIDE) {
325 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg, nextSreg + 1);
326 } else {
327 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
328 }
329 }
330 if (attrs & DF_DA) {
331 if (attrs & DF_A_WIDE) {
332 rlDest = oatGetDestWide(cUnit, mir, 0, 1);
333 } else {
334 rlDest = oatGetDest(cUnit, mir, 0);
335 }
336 }
337
338 switch (opcode) {
339 case Instruction::NOP:
340 break;
341
342 case Instruction::MOVE:
343 case Instruction::MOVE_OBJECT:
344 case Instruction::MOVE_16:
345 case Instruction::MOVE_OBJECT_16:
346 case Instruction::MOVE_FROM16:
347 case Instruction::MOVE_WIDE:
348 case Instruction::MOVE_WIDE_16:
349 case Instruction::MOVE_WIDE_FROM16: {
350 /*
351 * Moves/copies are meaningless in pure SSA register form,
352 * but we need to preserve them for the conversion back into
353 * MIR (at least until we stop using the Dalvik register maps).
354 * Insert a dummy intrinsic copy call, which will be recognized
355 * by the quick path and removed by the portable path.
356 */
357 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
358 llvm::Value* res = emitCopy(cUnit, src, rlDest);
359 defineValue(cUnit, res, rlDest.origSReg);
360 }
361 break;
362
363 case Instruction::CONST:
364 case Instruction::CONST_4:
365 case Instruction::CONST_16: {
366 llvm::Constant* immValue = cUnit->irb->GetJInt(mir->dalvikInsn.vB);
367 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
368 defineValue(cUnit, res, rlDest.origSReg);
369 }
370 break;
371
372 case Instruction::CONST_WIDE_16:
373 case Instruction::CONST_WIDE_32: {
374 llvm::Constant* immValue = cUnit->irb->GetJLong(mir->dalvikInsn.vB);
375 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
376 defineValue(cUnit, res, rlDest.origSReg);
377 }
378 break;
379
380 case Instruction::CONST_HIGH16: {
381 llvm::Constant* immValue = cUnit->irb->GetJInt(mir->dalvikInsn.vB << 16);
382 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
383 defineValue(cUnit, res, rlDest.origSReg);
384 }
385 break;
386
387 case Instruction::CONST_WIDE: {
388 llvm::Constant* immValue =
389 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
390 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
391 defineValue(cUnit, res, rlDest.origSReg);
392 }
393 case Instruction::CONST_WIDE_HIGH16: {
394 int64_t imm = static_cast<int64_t>(mir->dalvikInsn.vB) << 48;
395 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
396 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
397 defineValue(cUnit, res, rlDest.origSReg);
398 }
399
400 case Instruction::RETURN_WIDE:
401 case Instruction::RETURN:
402 case Instruction::RETURN_OBJECT: {
403 if (!cUnit->attrs & METHOD_IS_LEAF) {
404 emitSuspendCheck(cUnit);
405 }
406 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
407 bb->hasReturn = true;
408 }
409 break;
410
411 case Instruction::RETURN_VOID: {
412 if (!cUnit->attrs & METHOD_IS_LEAF) {
413 emitSuspendCheck(cUnit);
414 }
415 cUnit->irb->CreateRetVoid();
416 bb->hasReturn = true;
417 }
418 break;
419
420 case Instruction::IF_EQ:
421 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
422 break;
423 case Instruction::IF_NE:
424 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
425 break;
426 case Instruction::IF_LT:
427 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
428 break;
429 case Instruction::IF_GE:
430 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
431 break;
432 case Instruction::IF_GT:
433 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
434 break;
435 case Instruction::IF_LE:
436 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
437 break;
438 case Instruction::IF_EQZ:
439 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
440 break;
441 case Instruction::IF_NEZ:
442 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
443 break;
444 case Instruction::IF_LTZ:
445 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
446 break;
447 case Instruction::IF_GEZ:
448 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
449 break;
450 case Instruction::IF_GTZ:
451 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
452 break;
453 case Instruction::IF_LEZ:
454 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
455 break;
456
457 case Instruction::GOTO:
458 case Instruction::GOTO_16:
459 case Instruction::GOTO_32: {
460 if (bb->taken->startOffset <= bb->startOffset) {
461 emitSuspendCheck(cUnit);
462 }
463 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
464 }
465 break;
466
467 case Instruction::ADD_LONG:
468 case Instruction::ADD_LONG_2ADDR:
469 case Instruction::ADD_INT:
470 case Instruction::ADD_INT_2ADDR:
471 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
472 break;
473 case Instruction::SUB_LONG:
474 case Instruction::SUB_LONG_2ADDR:
475 case Instruction::SUB_INT:
476 case Instruction::SUB_INT_2ADDR:
477 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
478 break;
479 case Instruction::MUL_LONG:
480 case Instruction::MUL_LONG_2ADDR:
481 case Instruction::MUL_INT:
482 case Instruction::MUL_INT_2ADDR:
483 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
484 break;
485 case Instruction::DIV_LONG:
486 case Instruction::DIV_LONG_2ADDR:
487 case Instruction::DIV_INT:
488 case Instruction::DIV_INT_2ADDR:
489 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
490 break;
491 case Instruction::REM_LONG:
492 case Instruction::REM_LONG_2ADDR:
493 case Instruction::REM_INT:
494 case Instruction::REM_INT_2ADDR:
495 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
496 break;
497 case Instruction::AND_LONG:
498 case Instruction::AND_LONG_2ADDR:
499 case Instruction::AND_INT:
500 case Instruction::AND_INT_2ADDR:
501 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
502 break;
503 case Instruction::OR_LONG:
504 case Instruction::OR_LONG_2ADDR:
505 case Instruction::OR_INT:
506 case Instruction::OR_INT_2ADDR:
507 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
508 break;
509 case Instruction::XOR_LONG:
510 case Instruction::XOR_LONG_2ADDR:
511 case Instruction::XOR_INT:
512 case Instruction::XOR_INT_2ADDR:
513 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
514 break;
515 case Instruction::SHL_LONG:
516 case Instruction::SHL_LONG_2ADDR:
517 case Instruction::SHL_INT:
518 case Instruction::SHL_INT_2ADDR:
519 convertArithOp(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
520 break;
521 case Instruction::SHR_LONG:
522 case Instruction::SHR_LONG_2ADDR:
523 case Instruction::SHR_INT:
524 case Instruction::SHR_INT_2ADDR:
525 convertArithOp(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
526 break;
527 case Instruction::USHR_LONG:
528 case Instruction::USHR_LONG_2ADDR:
529 case Instruction::USHR_INT:
530 case Instruction::USHR_INT_2ADDR:
531 convertArithOp(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
532 break;
533
534 case Instruction::ADD_INT_LIT16:
535 case Instruction::ADD_INT_LIT8:
536 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], mir->dalvikInsn.vC);
537 break;
538 case Instruction::RSUB_INT:
539 case Instruction::RSUB_INT_LIT8:
540 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], mir->dalvikInsn.vC);
541 break;
542 case Instruction::MUL_INT_LIT16:
543 case Instruction::MUL_INT_LIT8:
544 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], mir->dalvikInsn.vC);
545 break;
546 case Instruction::DIV_INT_LIT16:
547 case Instruction::DIV_INT_LIT8:
548 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], mir->dalvikInsn.vC);
549 break;
550 case Instruction::REM_INT_LIT16:
551 case Instruction::REM_INT_LIT8:
552 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], mir->dalvikInsn.vC);
553 break;
554 case Instruction::AND_INT_LIT16:
555 case Instruction::AND_INT_LIT8:
556 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], mir->dalvikInsn.vC);
557 break;
558 case Instruction::OR_INT_LIT16:
559 case Instruction::OR_INT_LIT8:
560 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], mir->dalvikInsn.vC);
561 break;
562 case Instruction::XOR_INT_LIT16:
563 case Instruction::XOR_INT_LIT8:
564 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], mir->dalvikInsn.vC);
565 break;
566 case Instruction::SHL_INT_LIT8:
567 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], mir->dalvikInsn.vC);
568 break;
569 case Instruction::SHR_INT_LIT8:
570 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], mir->dalvikInsn.vC);
571 break;
572 case Instruction::USHR_INT_LIT8:
573 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], mir->dalvikInsn.vC);
574 break;
575
576 case Instruction::ADD_FLOAT:
577 case Instruction::ADD_FLOAT_2ADDR:
578 case Instruction::ADD_DOUBLE:
579 case Instruction::ADD_DOUBLE_2ADDR:
580 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
581 break;
582
583 case Instruction::SUB_FLOAT:
584 case Instruction::SUB_FLOAT_2ADDR:
585 case Instruction::SUB_DOUBLE:
586 case Instruction::SUB_DOUBLE_2ADDR:
587 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
588 break;
589
590 case Instruction::MUL_FLOAT:
591 case Instruction::MUL_FLOAT_2ADDR:
592 case Instruction::MUL_DOUBLE:
593 case Instruction::MUL_DOUBLE_2ADDR:
594 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
595 break;
596
597 case Instruction::DIV_FLOAT:
598 case Instruction::DIV_FLOAT_2ADDR:
599 case Instruction::DIV_DOUBLE:
600 case Instruction::DIV_DOUBLE_2ADDR:
601 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
602 break;
603
604 case Instruction::REM_FLOAT:
605 case Instruction::REM_FLOAT_2ADDR:
606 case Instruction::REM_DOUBLE:
607 case Instruction::REM_DOUBLE_2ADDR:
608 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
609 break;
610
611#if 0
612
613 case Instruction::MOVE_EXCEPTION: {
614 int exOffset = Thread::ExceptionOffset().Int32Value();
615 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
616#if defined(TARGET_X86)
617 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
618 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
619#else
620 int resetReg = oatAllocTemp(cUnit);
621 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
622 loadConstant(cUnit, resetReg, 0);
623 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
624 storeValue(cUnit, rlDest, rlResult);
625 oatFreeTemp(cUnit, resetReg);
626#endif
627 break;
628 }
629
630 case Instruction::MOVE_RESULT_WIDE:
631 if (mir->optimizationFlags & MIR_INLINED)
632 break; // Nop - combined w/ previous invoke
633 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
634 break;
635
636 case Instruction::MOVE_RESULT:
637 case Instruction::MOVE_RESULT_OBJECT:
638 if (mir->optimizationFlags & MIR_INLINED)
639 break; // Nop - combined w/ previous invoke
640 storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
641 break;
642
643 case Instruction::MONITOR_ENTER:
644 genMonitorEnter(cUnit, mir, rlSrc[0]);
645 break;
646
647 case Instruction::MONITOR_EXIT:
648 genMonitorExit(cUnit, mir, rlSrc[0]);
649 break;
650
651 case Instruction::CHECK_CAST:
652 genCheckCast(cUnit, mir, rlSrc[0]);
653 break;
654
655 case Instruction::INSTANCE_OF:
656 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
657 break;
658
659 case Instruction::NEW_INSTANCE:
660 genNewInstance(cUnit, mir, rlDest);
661 break;
662
663 case Instruction::THROW:
664 genThrow(cUnit, mir, rlSrc[0]);
665 break;
666
667 case Instruction::THROW_VERIFICATION_ERROR:
668 genThrowVerificationError(cUnit, mir);
669 break;
670
671 case Instruction::ARRAY_LENGTH:
672 int lenOffset;
673 lenOffset = Array::LengthOffset().Int32Value();
674 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
675 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
676 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
677 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
678 storeValue(cUnit, rlDest, rlResult);
679 break;
680
681 case Instruction::CONST_STRING:
682 case Instruction::CONST_STRING_JUMBO:
683 genConstString(cUnit, mir, rlDest, rlSrc[0]);
684 break;
685
686 case Instruction::CONST_CLASS:
687 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
688 break;
689
690 case Instruction::FILL_ARRAY_DATA:
691 genFillArrayData(cUnit, mir, rlSrc[0]);
692 break;
693
694 case Instruction::FILLED_NEW_ARRAY:
695 genFilledNewArray(cUnit, mir, false /* not range */);
696 break;
697
698 case Instruction::FILLED_NEW_ARRAY_RANGE:
699 genFilledNewArray(cUnit, mir, true /* range */);
700 break;
701
702 case Instruction::NEW_ARRAY:
703 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
704 break;
705
706 case Instruction::PACKED_SWITCH:
707 genPackedSwitch(cUnit, mir, rlSrc[0]);
708 break;
709
710 case Instruction::SPARSE_SWITCH:
711 genSparseSwitch(cUnit, mir, rlSrc[0], labelList);
712 break;
713
714 case Instruction::CMPL_FLOAT:
715 case Instruction::CMPG_FLOAT:
716 case Instruction::CMPL_DOUBLE:
717 case Instruction::CMPG_DOUBLE:
718 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
719 break;
720
721 case Instruction::CMP_LONG:
722 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
723 break;
724
725 case Instruction::AGET_WIDE:
726 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
727 break;
728 case Instruction::AGET:
729 case Instruction::AGET_OBJECT:
730 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
731 break;
732 case Instruction::AGET_BOOLEAN:
733 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
734 break;
735 case Instruction::AGET_BYTE:
736 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
737 break;
738 case Instruction::AGET_CHAR:
739 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
740 break;
741 case Instruction::AGET_SHORT:
742 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
743 break;
744 case Instruction::APUT_WIDE:
745 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
746 break;
747 case Instruction::APUT:
748 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
749 break;
750 case Instruction::APUT_OBJECT:
751 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
752 break;
753 case Instruction::APUT_SHORT:
754 case Instruction::APUT_CHAR:
755 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
756 break;
757 case Instruction::APUT_BYTE:
758 case Instruction::APUT_BOOLEAN:
759 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
760 rlSrc[0], 0);
761 break;
762
763 case Instruction::IGET_OBJECT:
764 //case Instruction::IGET_OBJECT_VOLATILE:
765 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
766 break;
767
768 case Instruction::IGET_WIDE:
769 //case Instruction::IGET_WIDE_VOLATILE:
770 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
771 break;
772
773 case Instruction::IGET:
774 //case Instruction::IGET_VOLATILE:
775 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
776 break;
777
778 case Instruction::IGET_CHAR:
779 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
780 break;
781
782 case Instruction::IGET_SHORT:
783 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
784 break;
785
786 case Instruction::IGET_BOOLEAN:
787 case Instruction::IGET_BYTE:
788 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
789 break;
790
791 case Instruction::IPUT_WIDE:
792 //case Instruction::IPUT_WIDE_VOLATILE:
793 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
794 break;
795
796 case Instruction::IPUT_OBJECT:
797 //case Instruction::IPUT_OBJECT_VOLATILE:
798 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
799 break;
800
801 case Instruction::IPUT:
802 //case Instruction::IPUT_VOLATILE:
803 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
804 break;
805
806 case Instruction::IPUT_BOOLEAN:
807 case Instruction::IPUT_BYTE:
808 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
809 break;
810
811 case Instruction::IPUT_CHAR:
812 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
813 break;
814
815 case Instruction::IPUT_SHORT:
816 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
817 break;
818
819 case Instruction::SGET_OBJECT:
820 genSget(cUnit, mir, rlDest, false, true);
821 break;
822 case Instruction::SGET:
823 case Instruction::SGET_BOOLEAN:
824 case Instruction::SGET_BYTE:
825 case Instruction::SGET_CHAR:
826 case Instruction::SGET_SHORT:
827 genSget(cUnit, mir, rlDest, false, false);
828 break;
829
830 case Instruction::SGET_WIDE:
831 genSget(cUnit, mir, rlDest, true, false);
832 break;
833
834 case Instruction::SPUT_OBJECT:
835 genSput(cUnit, mir, rlSrc[0], false, true);
836 break;
837
838 case Instruction::SPUT:
839 case Instruction::SPUT_BOOLEAN:
840 case Instruction::SPUT_BYTE:
841 case Instruction::SPUT_CHAR:
842 case Instruction::SPUT_SHORT:
843 genSput(cUnit, mir, rlSrc[0], false, false);
844 break;
845
846 case Instruction::SPUT_WIDE:
847 genSput(cUnit, mir, rlSrc[0], true, false);
848 break;
849
850 case Instruction::INVOKE_STATIC_RANGE:
851 genInvoke(cUnit, bb, mir, kStatic, true /*range*/);
852 break;
853 case Instruction::INVOKE_STATIC:
854 genInvoke(cUnit, bb, mir, kStatic, false /*range*/);
855 break;
856
857 case Instruction::INVOKE_DIRECT:
858 genInvoke(cUnit, bb, mir, kDirect, false /*range*/);
859 break;
860 case Instruction::INVOKE_DIRECT_RANGE:
861 genInvoke(cUnit, bb, mir, kDirect, true /*range*/);
862 break;
863
864 case Instruction::INVOKE_VIRTUAL:
865 genInvoke(cUnit, bb, mir, kVirtual, false /*range*/);
866 break;
867 case Instruction::INVOKE_VIRTUAL_RANGE:
868 genInvoke(cUnit, bb, mir, kVirtual, true /*range*/);
869 break;
870
871 case Instruction::INVOKE_SUPER:
872 genInvoke(cUnit, bb, mir, kSuper, false /*range*/);
873 break;
874 case Instruction::INVOKE_SUPER_RANGE:
875 genInvoke(cUnit, bb, mir, kSuper, true /*range*/);
876 break;
877
878 case Instruction::INVOKE_INTERFACE:
879 genInvoke(cUnit, bb, mir, kInterface, false /*range*/);
880 break;
881 case Instruction::INVOKE_INTERFACE_RANGE:
882 genInvoke(cUnit, bb, mir, kInterface, true /*range*/);
883 break;
884
885 case Instruction::NEG_INT:
886 case Instruction::NOT_INT:
887 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
888 break;
889
890 case Instruction::NEG_LONG:
891 case Instruction::NOT_LONG:
892 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
893 break;
894
895 case Instruction::NEG_FLOAT:
896 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
897 break;
898
899 case Instruction::NEG_DOUBLE:
900 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
901 break;
902
903 case Instruction::INT_TO_LONG:
904 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
905 break;
906
907 case Instruction::LONG_TO_INT:
908 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
909 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
910 storeValue(cUnit, rlDest, rlSrc[0]);
911 break;
912
913 case Instruction::INT_TO_BYTE:
914 case Instruction::INT_TO_SHORT:
915 case Instruction::INT_TO_CHAR:
916 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
917 break;
918
919 case Instruction::INT_TO_FLOAT:
920 case Instruction::INT_TO_DOUBLE:
921 case Instruction::LONG_TO_FLOAT:
922 case Instruction::LONG_TO_DOUBLE:
923 case Instruction::FLOAT_TO_INT:
924 case Instruction::FLOAT_TO_LONG:
925 case Instruction::FLOAT_TO_DOUBLE:
926 case Instruction::DOUBLE_TO_INT:
927 case Instruction::DOUBLE_TO_LONG:
928 case Instruction::DOUBLE_TO_FLOAT:
929 genConversion(cUnit, mir);
930 break;
931
932#endif
933
934 default:
935 res = true;
936 }
937 return res;
938}
939
940/* Extended MIR instructions like PHI */
941void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
942 llvm::BasicBlock* llvmBB)
943{
944
945 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
946 case kMirOpPhi: {
947 int* incoming = (int*)mir->dalvikInsn.vB;
948 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
949 llvm::Type* phiType =
950 llvmTypeFromLocRec(cUnit, rlDest);
951 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
952 for (int i = 0; i < mir->ssaRep->numUses; i++) {
953 RegLocation loc;
954 if (rlDest.wide) {
955 loc = oatGetSrcWide(cUnit, mir, i, i+1);
956 i++;
957 } else {
958 loc = oatGetSrc(cUnit, mir, i);
959 }
960 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
961 getLLVMBlock(cUnit, incoming[i]));
962 }
963 defineValue(cUnit, phi, rlDest.origSReg);
964 break;
965 }
966 case kMirOpCopy: {
967 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
968 break;
969 }
970#if defined(TARGET_ARM)
971 case kMirOpFusedCmplFloat:
972 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
973 break;
974 case kMirOpFusedCmpgFloat:
975 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
976 break;
977 case kMirOpFusedCmplDouble:
978 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
979 break;
980 case kMirOpFusedCmpgDouble:
981 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
982 break;
983 case kMirOpFusedCmpLong:
984 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
985 break;
986#endif
987 default:
988 break;
989 }
990}
991
992void setDexOffset(CompilationUnit* cUnit, int32_t offset)
993{
994 cUnit->currentDalvikOffset = offset;
995 llvm::SmallVector<llvm::Value*, 1>arrayRef;
996 arrayRef.push_back(cUnit->irb->getInt32(offset));
997 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
998 cUnit->irb->SetDexOffset(node);
999}
1000
1001// Attach method info as metadata to special intrinsic
1002void setMethodInfo(CompilationUnit* cUnit)
1003{
1004 // We don't want dex offset on this
1005 cUnit->irb->SetDexOffset(NULL);
1006 greenland::IntrinsicHelper::IntrinsicId id;
1007 id = greenland::IntrinsicHelper::MethodInfo;
1008 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1009 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1010 llvm::SmallVector<llvm::Value*, 2> regInfo;
1011 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1012 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1013 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1014 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1015 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1016 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1017 inst->setMetadata("RegInfo", regInfoNode);
1018 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1019 llvm::SmallVector<llvm::Value*, 50> pmap;
1020 for (int i = 0; i < promoSize; i++) {
1021 PromotionMap* p = &cUnit->promotionMap[i];
1022 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1023 ((p->fpReg & 0xff) << 16) |
1024 ((p->coreReg & 0xff) << 8) |
1025 ((p->fpLocation & 0xf) << 4) |
1026 (p->coreLocation & 0xf);
1027 pmap.push_back(cUnit->irb->getInt32(mapData));
1028 }
1029 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1030 inst->setMetadata("PromotionMap", mapNode);
1031 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1032}
1033
1034/* Handle the content in each basic block */
1035bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1036{
1037 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1038 cUnit->irb->SetInsertPoint(llvmBB);
1039 setDexOffset(cUnit, bb->startOffset);
1040
1041 if (bb->blockType == kEntryBlock) {
1042 setMethodInfo(cUnit);
1043 //genEntrySequence(cUnit, bb);
1044 } else if (bb->blockType == kExitBlock) {
1045 /*
1046 * Because of the differences between how MIR/LIR and llvm handle exit
1047 * blocks, we won't explicitly covert them. On the llvm-to-lir
1048 * path, it will need to be regenereated.
1049 */
1050 return false;
1051 }
1052
1053 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1054
1055 setDexOffset(cUnit, mir->offset);
1056
1057 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1058 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1059
1060 /* If we're compiling for the debugger, generate an update callout */
1061 if (cUnit->genDebugger) {
1062 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1063 //genDebuggerUpdate(cUnit, mir->offset);
1064 }
1065
1066 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1067 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1068 continue;
1069 }
1070
1071 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1072 NULL /* labelList */);
1073 if (notHandled) {
1074 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1075 mir->offset, dalvikOpcode,
1076 Instruction::Name(dalvikOpcode),
1077 dalvikFormat);
1078 }
1079 }
1080
1081 if ((bb->taken == NULL) && (bb->fallThrough != NULL) && !bb->hasReturn) {
1082 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1083 }
1084
1085 return false;
1086}
1087
1088llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1089
1090 // Get return type
1091 llvm::Type* ret_type = cUnit->irb->GetJType(cUnit->shorty[0],
1092 greenland::kAccurate);
1093
1094 // Get argument type
1095 std::vector<llvm::Type*> args_type;
1096
1097 // method object
1098 args_type.push_back(cUnit->irb->GetJMethodTy());
1099
1100 // Do we have a "this"?
1101 if ((cUnit->access_flags & kAccStatic) == 0) {
1102 args_type.push_back(cUnit->irb->GetJObjectTy());
1103 }
1104
1105 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
1106 args_type.push_back(cUnit->irb->GetJType(cUnit->shorty[i],
1107 greenland::kAccurate));
1108 }
1109
1110 return llvm::FunctionType::get(ret_type, args_type, false);
1111}
1112
1113bool createFunction(CompilationUnit* cUnit) {
1114 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1115 /* with_signature */ false));
1116 llvm::FunctionType* func_type = getFunctionType(cUnit);
1117
1118 if (func_type == NULL) {
1119 return false;
1120 }
1121
1122 cUnit->func = llvm::Function::Create(func_type,
1123 llvm::Function::ExternalLinkage,
1124 func_name, cUnit->module);
1125
1126 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1127 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1128
1129 arg_iter->setName("method");
1130 ++arg_iter;
1131
1132 int startSReg = cUnit->numRegs;
1133
1134 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1135 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1136 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1137 }
1138
1139 return true;
1140}
1141
1142bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1143{
1144 // Skip the exit block
1145 if (bb->blockType == kExitBlock) {
1146 cUnit->idToBlockMap.Put(bb->id, NULL);
1147 } else {
1148 int offset = bb->startOffset;
1149 bool entryBlock = (bb->blockType == kEntryBlock);
1150 llvm::BasicBlock* llvmBB =
1151 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
1152 StringPrintf(labelFormat, offset, bb->id),
1153 cUnit->func);
1154 if (entryBlock) {
1155 cUnit->entryBB = llvmBB;
1156 cUnit->placeholderBB =
1157 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1158 cUnit->func);
1159 }
1160 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1161 }
1162 return false;
1163}
1164
1165
1166/*
1167 * Convert MIR to LLVM_IR
1168 * o For each ssa name, create LLVM named value. Type these
1169 * appropriately, and ignore high half of wide and double operands.
1170 * o For each MIR basic block, create an LLVM basic block.
1171 * o Iterate through the MIR a basic block at a time, setting arguments
1172 * to recovered ssa name.
1173 */
1174void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1175{
1176 initIR(cUnit);
1177 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1178
1179 // Create the function
1180 createFunction(cUnit);
1181
1182 // Create an LLVM basic block for each MIR block in dfs preorder
1183 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1184 kPreOrderDFSTraversal, false /* isIterative */);
1185 /*
1186 * Create an llvm named value for each MIR SSA name. Note: we'll use
1187 * placeholders for all non-argument values (because we haven't seen
1188 * the definition yet).
1189 */
1190 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1191 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1192 arg_iter++; /* Skip path method */
1193 for (int i = 0; i < cUnit->numSSARegs; i++) {
1194 llvm::Value* val;
1195 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1196 if (i < cUnit->numRegs) {
1197 // Skip non-argument _0 names - should never be a use
1198 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1199 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1200 // Handle SSA defs, skipping Method* and compiler temps
1201 if (SRegToVReg(cUnit, i) < 0) {
1202 val = NULL;
1203 } else {
1204 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1205 val->setName(llvmSSAName(cUnit, i));
1206 }
1207 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1208 if (cUnit->regLocation[i].wide) {
1209 // Skip high half of wide values
1210 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1211 i++;
1212 }
1213 } else {
1214 // Recover previously-created argument values
1215 llvm::Value* argVal = arg_iter++;
1216 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
1217 }
1218 }
1219 cUnit->irb->CreateBr(cUnit->placeholderBB);
1220
1221 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1222 kPreOrderDFSTraversal, false /* Iterative */);
1223
1224 cUnit->placeholderBB->eraseFromParent();
1225
1226 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1227
1228 // Write bitcode to file
1229 std::string errmsg;
1230
1231 llvm::OwningPtr<llvm::tool_output_file> out_file(
1232 new llvm::tool_output_file("/tmp/foo.bc", errmsg,
1233 llvm::raw_fd_ostream::F_Binary));
1234
1235 if (!errmsg.empty()) {
1236 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1237 }
1238
1239 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1240 out_file->keep();
1241
1242
1243}
1244
1245RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1246 RegLocation res;
1247 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1248 if (it == cUnit->locMap.end()) {
1249 const char* valName = val->getName().str().c_str();
1250 DCHECK(valName != NULL);
1251 DCHECK(strlen(valName) > 0);
1252 if (valName[0] == 'v') {
1253 int baseSReg = INVALID_SREG;
1254 sscanf(valName, "v%d_", &baseSReg);
1255 res = cUnit->regLocation[baseSReg];
1256 cUnit->locMap.Put(val, res);
1257 } else {
1258 UNIMPLEMENTED(WARNING) << "Need to handle llvm temps";
1259 DCHECK(valName[0] == 't');
1260 }
1261 } else {
1262 res = it->second;
1263 }
1264 return res;
1265}
1266
1267Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1268{
1269 Instruction::Code res = Instruction::NOP;
1270 if (isWide) {
1271 switch(op) {
1272 case kOpAdd: res = Instruction::ADD_LONG; break;
1273 case kOpSub: res = Instruction::SUB_LONG; break;
1274 case kOpMul: res = Instruction::MUL_LONG; break;
1275 case kOpDiv: res = Instruction::DIV_LONG; break;
1276 case kOpRem: res = Instruction::REM_LONG; break;
1277 case kOpAnd: res = Instruction::AND_LONG; break;
1278 case kOpOr: res = Instruction::OR_LONG; break;
1279 case kOpXor: res = Instruction::XOR_LONG; break;
1280 case kOpLsl: res = Instruction::SHL_LONG; break;
1281 case kOpLsr: res = Instruction::USHR_LONG; break;
1282 case kOpAsr: res = Instruction::SHR_LONG; break;
1283 default: LOG(FATAL) << "Unexpected OpKind " << op;
1284 }
1285 } else if (isConst){
1286 switch(op) {
1287 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
1288 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
1289 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
1290 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
1291 case kOpRem: res = Instruction::REM_INT_LIT16; break;
1292 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
1293 case kOpOr: res = Instruction::OR_INT_LIT16; break;
1294 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
1295 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
1296 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
1297 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
1298 default: LOG(FATAL) << "Unexpected OpKind " << op;
1299 }
1300 } else {
1301 switch(op) {
1302 case kOpAdd: res = Instruction::ADD_INT; break;
1303 case kOpSub: res = Instruction::SUB_INT; break;
1304 case kOpMul: res = Instruction::MUL_INT; break;
1305 case kOpDiv: res = Instruction::DIV_INT; break;
1306 case kOpRem: res = Instruction::REM_INT; break;
1307 case kOpAnd: res = Instruction::AND_INT; break;
1308 case kOpOr: res = Instruction::OR_INT; break;
1309 case kOpXor: res = Instruction::XOR_INT; break;
1310 case kOpLsl: res = Instruction::SHL_INT; break;
1311 case kOpLsr: res = Instruction::USHR_INT; break;
1312 case kOpAsr: res = Instruction::SHR_INT; break;
1313 default: LOG(FATAL) << "Unexpected OpKind " << op;
1314 }
1315 }
1316 return res;
1317}
1318
1319void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1320{
1321 RegLocation rlDest = getLoc(cUnit, inst);
1322 llvm::Value* lhs = inst->getOperand(0);
1323 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
1324 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1325 llvm::Value* rhs = inst->getOperand(1);
1326 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1327 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
1328 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
1329 } else {
1330 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
1331 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1332 if (rlDest.wide) {
1333 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1334 } else {
1335 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1336 }
1337 }
1338}
1339
1340void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
1341{
1342 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
1343 DCHECK(brInst != NULL);
1344 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
1345 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
1346 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
1347}
1348
1349void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
1350{
1351 // Nop - these have already been processed
1352}
1353
1354void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
1355{
1356 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
1357 llvm::Value* retVal = retInst->getReturnValue();
1358 if (retVal != NULL) {
1359 RegLocation rlSrc = getLoc(cUnit, retVal);
1360 if (rlSrc.wide) {
1361 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
1362 } else {
1363 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
1364 }
1365 }
1366 genExitSequence(cUnit);
1367}
1368
1369ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
1370{
1371 ConditionCode res = kCondAl;
1372 switch(llvmCond) {
1373 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
1374 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
1375 default: LOG(FATAL) << "Unexpected llvm condition";
1376 }
1377 return res;
1378}
1379
1380void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
1381{
1382 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
1383 UNIMPLEMENTED(FATAL);
1384}
1385
1386void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
1387 llvm::BranchInst* brInst)
1388{
1389 // Get targets
1390 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
1391 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
1392 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
1393 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
1394 // Get comparison operands
1395 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
1396 ConditionCode cond = getCond(iCmpInst->getPredicate());
1397 llvm::Value* lhs = iCmpInst->getOperand(0);
1398 // Not expecting a constant as 1st operand
1399 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
1400 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1401 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
1402 llvm::Value* rhs = inst->getOperand(1);
1403#if defined(TARGET_MIPS)
1404 // Compare and branch in one shot
1405 (void)taken;
1406 (void)cond;
1407 (void)rhs;
1408 UNIMPLEMENTED(FATAL);
1409#else
1410 //Compare, then branch
1411 // TODO: handle fused CMP_LONG/IF_xxZ case
1412 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1413 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
1414 } else {
1415 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1416 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
1417 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
1418 }
1419 opCondBranch(cUnit, cond, taken);
1420#endif
1421 // Fallthrough
1422 opUnconditionalBranch(cUnit, fallThrough);
1423}
1424
1425void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
1426 llvm::Function* callee)
1427{
1428 UNIMPLEMENTED(FATAL);
1429}
1430
1431void setMethodInfo(CompilationUnit* cUnit, llvm::CallInst* callInst)
1432{
1433 UNIMPLEMENTED(WARNING) << "Net setMethodInfo";
1434}
1435
1436void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
1437{
1438 DCHECK(callInst->getNumArgOperands() == 1);
1439 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
1440 RegLocation rlDest = getLoc(cUnit, callInst);
1441 if (rlSrc.wide) {
1442 storeValueWide(cUnit, rlDest, rlSrc);
1443 } else {
1444 storeValue(cUnit, rlDest, rlSrc);
1445 }
1446}
1447
1448// Note: Immediate arg is a ConstantInt regardless of result type
1449void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
1450{
1451 DCHECK(callInst->getNumArgOperands() == 1);
1452 llvm::ConstantInt* src =
1453 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1454 uint64_t immval = src->getZExtValue();
1455 RegLocation rlDest = getLoc(cUnit, callInst);
1456 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
1457 if (rlDest.wide) {
1458 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
1459 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
1460 storeValueWide(cUnit, rlDest, rlResult);
1461 } else {
1462 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
1463 storeValue(cUnit, rlDest, rlResult);
1464 }
1465}
1466
1467bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
1468{
1469 bool isEntry = (bb == &cUnit->func->getEntryBlock());
1470 // Define the starting label
1471 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
1472 // Extract the starting offset from the block's name
1473 if (!isEntry) {
1474 const char* blockName = bb->getName().str().c_str();
1475 int dummy;
1476 sscanf(blockName, labelFormat, &blockLabel->operands[0], &dummy);
1477 }
1478 // Set the label kind
1479 blockLabel->opcode = kPseudoNormalBlockLabel;
1480 // Insert the label
1481 oatAppendLIR(cUnit, blockLabel);
1482
1483 // Free temp registers and reset redundant store tracking */
1484 oatResetRegPool(cUnit);
1485 oatResetDefTracking(cUnit);
1486
1487 //TODO: restore oat incoming liveness optimization
1488 oatClobberAllRegs(cUnit);
1489
1490 //LIR* headLIR = NULL;
1491
1492
1493 if (isEntry) {
1494 cUnit->currentDalvikOffset = 0;
1495 genEntrySequence(cUnit);
1496 }
1497
1498 // Visit all of the instructions in the block
1499 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
1500 llvm::Instruction* inst = it;
1501 llvm::BasicBlock::iterator nextIt = ++it;
1502 // Extract the Dalvik offset from the instruction
1503 uint32_t opcode = inst->getOpcode();
1504 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
1505 if (dexOffsetNode != NULL) {
1506 llvm::ConstantInt* dexOffsetValue =
1507 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
1508 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
1509 }
1510
1511 switch(opcode) {
1512
1513 case llvm::Instruction::ICmp: {
1514 llvm::Instruction* nextInst = nextIt;
1515 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
1516 if (brInst != NULL /* and... */) {
1517 cvtICmpBr(cUnit, inst, brInst);
1518 ++it;
1519 } else {
1520 cvtICmp(cUnit, inst);
1521 }
1522 }
1523 break;
1524
1525 case llvm::Instruction::Call: {
1526 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
1527 llvm::Function* callee = callInst->getCalledFunction();
1528 greenland::IntrinsicHelper::IntrinsicId id =
1529 cUnit->intrinsic_helper->GetIntrinsicId(callee);
1530 switch (id) {
1531 case greenland::IntrinsicHelper::CopyInt:
1532 case greenland::IntrinsicHelper::CopyObj:
1533 case greenland::IntrinsicHelper::CopyFloat:
1534 case greenland::IntrinsicHelper::CopyLong:
1535 case greenland::IntrinsicHelper::CopyDouble:
1536 cvtCopy(cUnit, callInst);
1537 break;
1538 case greenland::IntrinsicHelper::ConstInt:
1539 case greenland::IntrinsicHelper::ConstObj:
1540 case greenland::IntrinsicHelper::ConstLong:
1541 case greenland::IntrinsicHelper::ConstFloat:
1542 case greenland::IntrinsicHelper::ConstDouble:
1543 cvtConst(cUnit, callInst);
1544 break;
1545 case greenland::IntrinsicHelper::MethodInfo:
1546 setMethodInfo(cUnit, callInst);
1547 break;
1548 case greenland::IntrinsicHelper::CheckSuspend:
1549 genSuspendTest(cUnit, 0 /* optFlags already applied */);
1550 break;
1551 case greenland::IntrinsicHelper::UnknownId:
1552 cvtCall(cUnit, callInst, callee);
1553 break;
1554 default:
1555 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
1556 << cUnit->intrinsic_helper->GetName(id);
1557 }
1558 }
1559 break;
1560
1561 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
1562 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
1563 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
1564 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
1565 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
1566 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
1567 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
1568 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
1569 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
1570 case llvm::Instruction::Shl: cvtBinOp(cUnit, kOpLsl, inst); break;
1571 case llvm::Instruction::LShr: cvtBinOp(cUnit, kOpLsr, inst); break;
1572 case llvm::Instruction::AShr: cvtBinOp(cUnit, kOpAsr, inst); break;
1573 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
1574 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
1575
1576 case llvm::Instruction::Invoke:
1577 case llvm::Instruction::FAdd:
1578 case llvm::Instruction::FSub:
1579 case llvm::Instruction::FMul:
1580 case llvm::Instruction::FDiv:
1581 case llvm::Instruction::FRem:
1582 case llvm::Instruction::Trunc:
1583 case llvm::Instruction::ZExt:
1584 case llvm::Instruction::SExt:
1585 case llvm::Instruction::FPToUI:
1586 case llvm::Instruction::FPToSI:
1587 case llvm::Instruction::UIToFP:
1588 case llvm::Instruction::SIToFP:
1589 case llvm::Instruction::FPTrunc:
1590 case llvm::Instruction::FPExt:
1591 case llvm::Instruction::PtrToInt:
1592 case llvm::Instruction::IntToPtr:
1593 case llvm::Instruction::Switch:
1594 case llvm::Instruction::FCmp:
1595 UNIMPLEMENTED(FATAL) << "Unimplemented llvm opcode: " << opcode; break;
1596
1597 case llvm::Instruction::URem:
1598 case llvm::Instruction::UDiv:
1599 case llvm::Instruction::Resume:
1600 case llvm::Instruction::Unreachable:
1601 case llvm::Instruction::Alloca:
1602 case llvm::Instruction::GetElementPtr:
1603 case llvm::Instruction::Fence:
1604 case llvm::Instruction::AtomicCmpXchg:
1605 case llvm::Instruction::AtomicRMW:
1606 case llvm::Instruction::BitCast:
1607 case llvm::Instruction::VAArg:
1608 case llvm::Instruction::Select:
1609 case llvm::Instruction::UserOp1:
1610 case llvm::Instruction::UserOp2:
1611 case llvm::Instruction::ExtractElement:
1612 case llvm::Instruction::InsertElement:
1613 case llvm::Instruction::ShuffleVector:
1614 case llvm::Instruction::ExtractValue:
1615 case llvm::Instruction::InsertValue:
1616 case llvm::Instruction::LandingPad:
1617 case llvm::Instruction::IndirectBr:
1618 case llvm::Instruction::Load:
1619 case llvm::Instruction::Store:
1620 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
1621
1622 default:
1623 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
1624 }
1625 }
1626 return false;
1627}
1628
1629/*
1630 * Convert LLVM_IR to MIR:
1631 * o Iterate through the LLVM_IR and construct a graph using
1632 * standard MIR building blocks.
1633 * o Perform a basic-block optimization pass to remove unnecessary
1634 * store/load sequences.
1635 * o Convert the LLVM Value operands into RegLocations where applicable.
1636 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
1637 * o Perform register promotion
1638 * o Iterate through the graph a basic block at a time, generating
1639 * LIR.
1640 * o Assemble LIR as usual.
1641 * o Profit.
1642 */
1643void oatMethodBitcode2LIR(CompilationUnit* cUnit)
1644{
1645 int numBasicBlocks = cUnit->func->getBasicBlockList().size();
1646 // Allocate a list for LIR basic block labels
1647 cUnit->blockLabelList =
1648 (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
1649 LIR* labelList = (LIR*)cUnit->blockLabelList;
1650 int nextLabel = 0;
1651 for (llvm::Function::iterator i = cUnit->func->begin(),
1652 e = cUnit->func->end(); i != e; ++i) {
1653 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
1654 &labelList[nextLabel++]);
1655 }
1656 // Walk the blocks, generating code.
1657 for (llvm::Function::iterator i = cUnit->func->begin(),
1658 e = cUnit->func->end(); i != e; ++i) {
1659 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
1660 }
1661
1662 handleSuspendLaunchpads(cUnit);
1663
1664 handleThrowLaunchpads(cUnit);
1665
1666 handleIntrinsicLaunchpads(cUnit);
1667
1668 freeIR(cUnit);
1669}
1670
1671
1672} // namespace art
1673
1674#endif // ART_USE_QUICK_COMPILER