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