blob: cf990ec79af44190257047eea271785a326c97d1 [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>
buzbeead8f15e2012-06-18 14:49:45 -070030#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070031
Elliott Hughes74847412012-06-20 18:10:21 -070032static const char* kLabelFormat = "L0x%x_%d";
buzbee2cfc6392012-05-07 14:51:40 -070033
34namespace art {
35extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070036RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070037
38llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
39{
40 return cUnit->idToBlockMap.Get(id);
41}
42
43llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
44{
45 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
46}
47
48// Replace the placeholder value with the real definition
49void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
50{
51 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
52 CHECK(placeholder != NULL) << "Null placeholder - shouldn't happen";
53 placeholder->replaceAllUsesWith(val);
54 val->takeName(placeholder);
55 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
56}
57
58llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
59{
60 llvm::Type* res = NULL;
61 if (loc.wide) {
62 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070063 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070064 else
buzbee4f1181f2012-06-22 13:52:12 -070065 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070066 } else {
67 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070068 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070069 } else {
70 if (loc.ref)
71 res = cUnit->irb->GetJObjectTy();
72 else
buzbee4f1181f2012-06-22 13:52:12 -070073 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070074 }
75 }
76 return res;
77}
78
buzbeead8f15e2012-06-18 14:49:45 -070079/* Create an in-memory RegLocation from an llvm Value. */
80void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
81{
82 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
83 std::string s(val->getName().str());
84 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070085 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
86 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
87 int baseSReg = INVALID_SREG;
88 int subscript = -1;
89 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
90 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
91 baseSReg = SSA_METHOD_BASEREG;
92 subscript = 0;
93 }
buzbeead8f15e2012-06-18 14:49:45 -070094 DCHECK_NE(baseSReg, INVALID_SREG);
95 DCHECK_NE(subscript, -1);
96 // TODO: redo during C++'ification
97 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
98 INVALID_REG, INVALID_SREG, INVALID_SREG};
99 llvm::Type* ty = val->getType();
100 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
101 (ty == cUnit->irb->getDoubleTy()));
102 loc.defined = true;
103 if ((ty == cUnit->irb->getFloatTy()) ||
104 (ty == cUnit->irb->getDoubleTy())) {
105 loc.fp = true;
106 } else if (ty == cUnit->irb->GetJObjectTy()) {
107 loc.ref = true;
108 } else {
109 loc.core = true;
110 }
111 loc.home = false; // Will change during promotion
112 loc.sRegLow = baseSReg;
113 loc.origSReg = cUnit->locMap.size();
114 cUnit->locMap.Put(val, loc);
115}
116
buzbee2cfc6392012-05-07 14:51:40 -0700117void initIR(CompilationUnit* cUnit)
118{
119 cUnit->context = new llvm::LLVMContext();
120 cUnit->module = new llvm::Module("art", *cUnit->context);
121 llvm::StructType::create(*cUnit->context, "JavaObject");
122 llvm::StructType::create(*cUnit->context, "Method");
123 llvm::StructType::create(*cUnit->context, "Thread");
124 cUnit->intrinsic_helper =
125 new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
126 cUnit->irb =
127 new greenland::IRBuilder(*cUnit->context, *cUnit->module,
128 *cUnit->intrinsic_helper);
129}
130
131void freeIR(CompilationUnit* cUnit)
132{
133 delete cUnit->irb;
134 delete cUnit->intrinsic_helper;
135 delete cUnit->module;
136 delete cUnit->context;
137}
138
139const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
140 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
141}
142
buzbee4f1181f2012-06-22 13:52:12 -0700143llvm::Value* emitSget(CompilationUnit* cUnit,
144 greenland::IntrinsicHelper::IntrinsicId id,
145 llvm::ArrayRef<llvm::Value*> src, RegLocation Loc)
146{
147 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
148 return cUnit->irb->CreateCall(intr, src);
149}
150
buzbee2cfc6392012-05-07 14:51:40 -0700151llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
152 RegLocation loc)
153{
154 greenland::IntrinsicHelper::IntrinsicId id;
155 if (loc.wide) {
156 if (loc.fp) {
157 id = greenland::IntrinsicHelper::ConstDouble;
158 } else {
159 id = greenland::IntrinsicHelper::ConstLong;
160 }
161 } else {
162 if (loc.fp) {
163 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700164 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700165 id = greenland::IntrinsicHelper::ConstObj;
166 } else {
167 id = greenland::IntrinsicHelper::ConstInt;
168 }
169 }
170 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
171 return cUnit->irb->CreateCall(intr, src);
172}
buzbeeb03f4872012-06-11 15:22:11 -0700173
174void emitPopShadowFrame(CompilationUnit* cUnit)
175{
176 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
177 greenland::IntrinsicHelper::PopShadowFrame);
178 cUnit->irb->CreateCall(intr);
179}
180
181
182
buzbee2cfc6392012-05-07 14:51:40 -0700183llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
184 RegLocation loc)
185{
186 greenland::IntrinsicHelper::IntrinsicId id;
187 if (loc.wide) {
188 if (loc.fp) {
189 id = greenland::IntrinsicHelper::CopyDouble;
190 } else {
191 id = greenland::IntrinsicHelper::CopyLong;
192 }
193 } else {
194 if (loc.fp) {
195 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700196 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700197 id = greenland::IntrinsicHelper::CopyObj;
198 } else {
199 id = greenland::IntrinsicHelper::CopyInt;
200 }
201 }
202 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
203 return cUnit->irb->CreateCall(intr, src);
204}
205
buzbee32412962012-06-26 16:27:56 -0700206void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
207{
208 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
209 greenland::IntrinsicHelper::GetException);
210 llvm::Value* res = cUnit->irb->CreateCall(func);
211 defineValue(cUnit, res, rlDest.origSReg);
212}
213
214void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
215{
216 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
217 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
218 greenland::IntrinsicHelper::Throw);
219 cUnit->irb->CreateCall(func, src);
220 cUnit->irb->CreateUnreachable();
221}
222
223void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
224{
225 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
226 greenland::IntrinsicHelper::Throw);
227 llvm::SmallVector<llvm::Value*, 2> args;
228 args.push_back(cUnit->irb->getInt32(info1));
229 args.push_back(cUnit->irb->getInt32(info2));
230 cUnit->irb->CreateCall(func, args);
231 cUnit->irb->CreateUnreachable();
232}
233
buzbee2cfc6392012-05-07 14:51:40 -0700234void emitSuspendCheck(CompilationUnit* cUnit)
235{
236 greenland::IntrinsicHelper::IntrinsicId id =
237 greenland::IntrinsicHelper::CheckSuspend;
238 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
239 cUnit->irb->CreateCall(intr);
240}
241
242llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
243 llvm::Value* src1, llvm::Value* src2)
244{
245 llvm::Value* res = NULL;
246 switch(cc) {
247 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
248 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
249 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
250 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
251 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
252 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
253 default: LOG(FATAL) << "Unexpected cc value " << cc;
254 }
255 return res;
256}
257
258void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
259 ConditionCode cc, RegLocation rlSrc1,
260 RegLocation rlSrc2)
261{
262 if (bb->taken->startOffset <= mir->offset) {
263 emitSuspendCheck(cUnit);
264 }
265 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
266 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
267 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
268 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
269 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
270 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700271 // Don't redo the fallthrough branch in the BB driver
272 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700273}
274
275void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
276 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
277{
278 if (bb->taken->startOffset <= mir->offset) {
279 emitSuspendCheck(cUnit);
280 }
281 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
282 llvm::Value* src2;
283 if (rlSrc1.ref) {
284 src2 = cUnit->irb->GetJNull();
285 } else {
286 src2 = cUnit->irb->getInt32(0);
287 }
288 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
289 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
290 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
291 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700292 // Don't redo the fallthrough branch in the BB driver
293 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700294}
295
296llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
297 llvm::Value* src1, llvm::Value* src2)
298{
299 greenland::IntrinsicHelper::IntrinsicId id;
300 if (isLong) {
301 if (isDiv) {
302 id = greenland::IntrinsicHelper::DivLong;
303 } else {
304 id = greenland::IntrinsicHelper::RemLong;
305 }
306 } else if (isDiv) {
307 id = greenland::IntrinsicHelper::DivInt;
308 } else {
309 id = greenland::IntrinsicHelper::RemInt;
310 }
311 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
312 llvm::SmallVector<llvm::Value*, 2>args;
313 args.push_back(src1);
314 args.push_back(src2);
315 return cUnit->irb->CreateCall(intr, args);
316}
317
318llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
319 llvm::Value* src1, llvm::Value* src2)
320{
321 llvm::Value* res = NULL;
322 switch(op) {
323 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
324 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700325 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700326 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
327 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
328 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
329 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
330 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
331 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700332 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
333 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
334 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700335 default:
336 LOG(FATAL) << "Invalid op " << op;
337 }
338 return res;
339}
340
341void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
342 RegLocation rlSrc1, RegLocation rlSrc2)
343{
344 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
345 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
346 llvm::Value* res = NULL;
buzbee4f1181f2012-06-22 13:52:12 -0700347LOG(INFO) << "in convertFPArithOp";
buzbee2cfc6392012-05-07 14:51:40 -0700348 switch(op) {
349 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
350 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
351 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
352 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
353 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
354 default:
355 LOG(FATAL) << "Invalid op " << op;
356 }
357 defineValue(cUnit, res, rlDest.origSReg);
358}
359
buzbee4f1181f2012-06-22 13:52:12 -0700360void convertShift(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
361 RegLocation rlSrc1, RegLocation rlSrc2)
362{
363 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
364 llvm::Value* src2a = getLLVMValue(cUnit, rlSrc2.origSReg);
365 llvm::Value* src2b;
366 // Limit shift counnt to 63 for long and 31 for int
367 if (rlDest.wide) {
368 // Note: creates 2 unnamed temps
369 llvm::Value* t1 = cUnit->irb->CreateAnd(src2a, 0x3f);
370 src2b = cUnit->irb->CreateZExt(t1, cUnit->irb->getInt64Ty());
371 } else {
372 // Note: creates 1 unnamed temp
373 src2b = cUnit->irb->CreateAnd(src2a, 0x1f);
374 }
375 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2b);
376 defineValue(cUnit, res, rlDest.origSReg);
377}
378
buzbee2cfc6392012-05-07 14:51:40 -0700379void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
380 RegLocation rlSrc1, RegLocation rlSrc2)
381{
382 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
383 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
384 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
385 defineValue(cUnit, res, rlDest.origSReg);
386}
387
buzbeeb03f4872012-06-11 15:22:11 -0700388void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
389{
390 int index = -1;
391 DCHECK(newVal != NULL);
392 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
393 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
394 if (cUnit->shadowMap[i] == vReg) {
395 index = i;
396 break;
397 }
398 }
Elliott Hughes74847412012-06-20 18:10:21 -0700399 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700400 greenland::IntrinsicHelper::IntrinsicId id =
401 greenland::IntrinsicHelper::SetShadowFrameEntry;
402 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
403 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
404 llvm::Value* args[] = { newVal, tableSlot };
405 cUnit->irb->CreateCall(func, args);
406}
407
buzbee2cfc6392012-05-07 14:51:40 -0700408void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
409 RegLocation rlSrc1, int32_t imm)
410{
411 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
412 llvm::Value* src2 = cUnit->irb->getInt32(imm);
413 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
414 defineValue(cUnit, res, rlDest.origSReg);
415}
416
buzbee6969d502012-06-15 16:40:31 -0700417void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
418 InvokeType invokeType, bool isRange)
419{
420 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
421 llvm::SmallVector<llvm::Value*, 10> args;
422 // Insert the invokeType
423 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
424 // Insert the method_idx
425 args.push_back(cUnit->irb->getInt32(info->index));
426 // Insert the optimization flags
427 args.push_back(cUnit->irb->getInt32(info->optFlags));
428 // Now, insert the actual arguments
429 if (cUnit->printMe) {
430 LOG(INFO) << "Building Invoke info";
431 }
432 for (int i = 0; i < info->numArgWords;) {
433 if (cUnit->printMe) {
434 oatDumpRegLoc(info->args[i]);
435 }
436 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
437 args.push_back(val);
438 i += info->args[i].wide ? 2 : 1;
439 }
440 /*
441 * Choose the invoke return type based on actual usage. Note: may
442 * be different than shorty. For example, if a function return value
443 * is not used, we'll treat this as a void invoke.
444 */
445 greenland::IntrinsicHelper::IntrinsicId id;
446 if (info->result.location == kLocInvalid) {
447 id = greenland::IntrinsicHelper::HLInvokeVoid;
448 } else {
449 if (info->result.wide) {
450 if (info->result.fp) {
451 id = greenland::IntrinsicHelper::HLInvokeDouble;
452 } else {
453 id = greenland::IntrinsicHelper::HLInvokeFloat;
454 }
455 } else if (info->result.ref) {
456 id = greenland::IntrinsicHelper::HLInvokeObj;
457 } else if (info->result.fp) {
458 id = greenland::IntrinsicHelper::HLInvokeFloat;
459 } else {
460 id = greenland::IntrinsicHelper::HLInvokeInt;
461 }
462 }
463 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
464 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
465 if (info->result.location != kLocInvalid) {
466 defineValue(cUnit, res, info->result.origSReg);
467 }
468}
469
470void convertConstString(CompilationUnit* cUnit, BasicBlock* bb,
471 uint32_t string_idx, RegLocation rlDest)
472{
473 greenland::IntrinsicHelper::IntrinsicId id;
474 id = greenland::IntrinsicHelper::ConstString;
475 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
476 llvm::Value* index = cUnit->irb->getInt32(string_idx);
477 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
478 defineValue(cUnit, res, rlDest.origSReg);
479}
480
buzbee4f1181f2012-06-22 13:52:12 -0700481void convertNewInstance(CompilationUnit* cUnit, BasicBlock* bb,
482 uint32_t type_idx, RegLocation rlDest)
483{
484 greenland::IntrinsicHelper::IntrinsicId id;
485 id = greenland::IntrinsicHelper::NewInstance;
486 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
487 llvm::Value* index = cUnit->irb->getInt32(type_idx);
488 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
489 defineValue(cUnit, res, rlDest.origSReg);
490}
491
buzbee2cfc6392012-05-07 14:51:40 -0700492/*
493 * Target-independent code generation. Use only high-level
494 * load/store utilities here, or target-dependent genXX() handlers
495 * when necessary.
496 */
497bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
498 llvm::BasicBlock* llvmBB, LIR* labelList)
499{
500 bool res = false; // Assume success
501 RegLocation rlSrc[3];
502 RegLocation rlDest = badLoc;
503 RegLocation rlResult = badLoc;
504 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700505 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700506 uint32_t vB = mir->dalvikInsn.vB;
507 uint32_t vC = mir->dalvikInsn.vC;
508
buzbeeb03f4872012-06-11 15:22:11 -0700509 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700510
511 /* Prep Src and Dest locations */
512 int nextSreg = 0;
513 int nextLoc = 0;
514 int attrs = oatDataFlowAttributes[opcode];
515 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
516 if (attrs & DF_UA) {
517 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700518 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700519 nextSreg+= 2;
520 } else {
521 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
522 nextSreg++;
523 }
524 }
525 if (attrs & DF_UB) {
526 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700527 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700528 nextSreg+= 2;
529 } else {
530 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
531 nextSreg++;
532 }
533 }
534 if (attrs & DF_UC) {
535 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700536 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700537 } else {
538 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
539 }
540 }
541 if (attrs & DF_DA) {
542 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700543 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700544 } else {
buzbee15bf9802012-06-12 17:49:27 -0700545 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700546 if (rlDest.ref) {
547 objectDefinition = true;
548 }
buzbee2cfc6392012-05-07 14:51:40 -0700549 }
550 }
551
552 switch (opcode) {
553 case Instruction::NOP:
554 break;
555
556 case Instruction::MOVE:
557 case Instruction::MOVE_OBJECT:
558 case Instruction::MOVE_16:
559 case Instruction::MOVE_OBJECT_16:
560 case Instruction::MOVE_FROM16:
561 case Instruction::MOVE_WIDE:
562 case Instruction::MOVE_WIDE_16:
563 case Instruction::MOVE_WIDE_FROM16: {
564 /*
565 * Moves/copies are meaningless in pure SSA register form,
566 * but we need to preserve them for the conversion back into
567 * MIR (at least until we stop using the Dalvik register maps).
568 * Insert a dummy intrinsic copy call, which will be recognized
569 * by the quick path and removed by the portable path.
570 */
571 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
572 llvm::Value* res = emitCopy(cUnit, src, rlDest);
573 defineValue(cUnit, res, rlDest.origSReg);
574 }
575 break;
576
577 case Instruction::CONST:
578 case Instruction::CONST_4:
579 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700580 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700581 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
582 defineValue(cUnit, res, rlDest.origSReg);
583 }
584 break;
585
586 case Instruction::CONST_WIDE_16:
587 case Instruction::CONST_WIDE_32: {
buzbee6969d502012-06-15 16:40:31 -0700588 llvm::Constant* immValue = cUnit->irb->GetJLong(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700589 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
590 defineValue(cUnit, res, rlDest.origSReg);
591 }
592 break;
593
594 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700595 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700596 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
597 defineValue(cUnit, res, rlDest.origSReg);
598 }
599 break;
600
601 case Instruction::CONST_WIDE: {
602 llvm::Constant* immValue =
603 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
604 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
605 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700606 }
607 break;
buzbee2cfc6392012-05-07 14:51:40 -0700608 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700609 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700610 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
611 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
612 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700613 }
614 break;
615
616 case Instruction::SGET_OBJECT: {
617 llvm::Constant* fieldIdx = cUnit->irb->GetJInt(vB);
618 llvm::Value* res = emitSget(cUnit, greenland::IntrinsicHelper::SgetObj,
619 fieldIdx, rlDest);
620 defineValue(cUnit, res, rlDest.origSReg);
621 }
622 break;
buzbee2cfc6392012-05-07 14:51:40 -0700623
624 case Instruction::RETURN_WIDE:
625 case Instruction::RETURN:
626 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700627 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700628 emitSuspendCheck(cUnit);
629 }
buzbeeb03f4872012-06-11 15:22:11 -0700630 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700631 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
632 bb->hasReturn = true;
633 }
634 break;
635
636 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -0700637 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700638 emitSuspendCheck(cUnit);
639 }
buzbeeb03f4872012-06-11 15:22:11 -0700640 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700641 cUnit->irb->CreateRetVoid();
642 bb->hasReturn = true;
643 }
644 break;
645
646 case Instruction::IF_EQ:
647 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
648 break;
649 case Instruction::IF_NE:
650 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
651 break;
652 case Instruction::IF_LT:
653 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
654 break;
655 case Instruction::IF_GE:
656 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
657 break;
658 case Instruction::IF_GT:
659 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
660 break;
661 case Instruction::IF_LE:
662 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
663 break;
664 case Instruction::IF_EQZ:
665 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
666 break;
667 case Instruction::IF_NEZ:
668 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
669 break;
670 case Instruction::IF_LTZ:
671 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
672 break;
673 case Instruction::IF_GEZ:
674 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
675 break;
676 case Instruction::IF_GTZ:
677 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
678 break;
679 case Instruction::IF_LEZ:
680 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
681 break;
682
683 case Instruction::GOTO:
684 case Instruction::GOTO_16:
685 case Instruction::GOTO_32: {
686 if (bb->taken->startOffset <= bb->startOffset) {
687 emitSuspendCheck(cUnit);
688 }
689 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
690 }
691 break;
692
693 case Instruction::ADD_LONG:
694 case Instruction::ADD_LONG_2ADDR:
695 case Instruction::ADD_INT:
696 case Instruction::ADD_INT_2ADDR:
697 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
698 break;
699 case Instruction::SUB_LONG:
700 case Instruction::SUB_LONG_2ADDR:
701 case Instruction::SUB_INT:
702 case Instruction::SUB_INT_2ADDR:
703 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
704 break;
705 case Instruction::MUL_LONG:
706 case Instruction::MUL_LONG_2ADDR:
707 case Instruction::MUL_INT:
708 case Instruction::MUL_INT_2ADDR:
709 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
710 break;
711 case Instruction::DIV_LONG:
712 case Instruction::DIV_LONG_2ADDR:
713 case Instruction::DIV_INT:
714 case Instruction::DIV_INT_2ADDR:
715 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
716 break;
717 case Instruction::REM_LONG:
718 case Instruction::REM_LONG_2ADDR:
719 case Instruction::REM_INT:
720 case Instruction::REM_INT_2ADDR:
721 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
722 break;
723 case Instruction::AND_LONG:
724 case Instruction::AND_LONG_2ADDR:
725 case Instruction::AND_INT:
726 case Instruction::AND_INT_2ADDR:
727 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
728 break;
729 case Instruction::OR_LONG:
730 case Instruction::OR_LONG_2ADDR:
731 case Instruction::OR_INT:
732 case Instruction::OR_INT_2ADDR:
733 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
734 break;
735 case Instruction::XOR_LONG:
736 case Instruction::XOR_LONG_2ADDR:
737 case Instruction::XOR_INT:
738 case Instruction::XOR_INT_2ADDR:
739 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
740 break;
741 case Instruction::SHL_LONG:
742 case Instruction::SHL_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700743 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
744 break;
buzbee2cfc6392012-05-07 14:51:40 -0700745 case Instruction::SHL_INT:
746 case Instruction::SHL_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700747 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700748 break;
749 case Instruction::SHR_LONG:
750 case Instruction::SHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700751 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
752 break;
buzbee2cfc6392012-05-07 14:51:40 -0700753 case Instruction::SHR_INT:
754 case Instruction::SHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700755 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700756 break;
757 case Instruction::USHR_LONG:
758 case Instruction::USHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700759 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
760 break;
buzbee2cfc6392012-05-07 14:51:40 -0700761 case Instruction::USHR_INT:
762 case Instruction::USHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700763 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700764 break;
765
766 case Instruction::ADD_INT_LIT16:
767 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700768 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700769 break;
770 case Instruction::RSUB_INT:
771 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700772 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700773 break;
774 case Instruction::MUL_INT_LIT16:
775 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700776 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700777 break;
778 case Instruction::DIV_INT_LIT16:
779 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700780 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700781 break;
782 case Instruction::REM_INT_LIT16:
783 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700784 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700785 break;
786 case Instruction::AND_INT_LIT16:
787 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700788 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700789 break;
790 case Instruction::OR_INT_LIT16:
791 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700792 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700793 break;
794 case Instruction::XOR_INT_LIT16:
795 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700796 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700797 break;
798 case Instruction::SHL_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -0700799 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -0700800 break;
801 case Instruction::SHR_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -0700802 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -0700803 break;
804 case Instruction::USHR_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -0700805 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -0700806 break;
807
808 case Instruction::ADD_FLOAT:
809 case Instruction::ADD_FLOAT_2ADDR:
810 case Instruction::ADD_DOUBLE:
811 case Instruction::ADD_DOUBLE_2ADDR:
812 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
813 break;
814
815 case Instruction::SUB_FLOAT:
816 case Instruction::SUB_FLOAT_2ADDR:
817 case Instruction::SUB_DOUBLE:
818 case Instruction::SUB_DOUBLE_2ADDR:
819 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
820 break;
821
822 case Instruction::MUL_FLOAT:
823 case Instruction::MUL_FLOAT_2ADDR:
824 case Instruction::MUL_DOUBLE:
825 case Instruction::MUL_DOUBLE_2ADDR:
826 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
827 break;
828
829 case Instruction::DIV_FLOAT:
830 case Instruction::DIV_FLOAT_2ADDR:
831 case Instruction::DIV_DOUBLE:
832 case Instruction::DIV_DOUBLE_2ADDR:
833 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
834 break;
835
836 case Instruction::REM_FLOAT:
837 case Instruction::REM_FLOAT_2ADDR:
838 case Instruction::REM_DOUBLE:
839 case Instruction::REM_DOUBLE_2ADDR:
840 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
841 break;
842
buzbee6969d502012-06-15 16:40:31 -0700843 case Instruction::INVOKE_STATIC:
844 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/);
845 break;
846 case Instruction::INVOKE_STATIC_RANGE:
847 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/);
848 break;
849
850 case Instruction::INVOKE_DIRECT:
851 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/);
852 break;
853 case Instruction::INVOKE_DIRECT_RANGE:
854 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/);
855 break;
856
857 case Instruction::INVOKE_VIRTUAL:
858 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/);
859 break;
860 case Instruction::INVOKE_VIRTUAL_RANGE:
861 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/);
862 break;
863
864 case Instruction::INVOKE_SUPER:
865 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/);
866 break;
867 case Instruction::INVOKE_SUPER_RANGE:
868 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/);
869 break;
870
871 case Instruction::INVOKE_INTERFACE:
872 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/);
873 break;
874 case Instruction::INVOKE_INTERFACE_RANGE:
875 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/);
876 break;
877
878 case Instruction::CONST_STRING:
879 case Instruction::CONST_STRING_JUMBO:
880 convertConstString(cUnit, bb, vB, rlDest);
881 break;
882
buzbee4f1181f2012-06-22 13:52:12 -0700883 case Instruction::NEW_INSTANCE:
884 convertNewInstance(cUnit, bb, vB, rlDest);
885 break;
886
buzbee32412962012-06-26 16:27:56 -0700887 case Instruction::MOVE_EXCEPTION:
888 convertMoveException(cUnit, rlDest);
889 break;
890
891 case Instruction::THROW:
892 convertThrow(cUnit, rlSrc[0]);
893 break;
894
895 case Instruction::THROW_VERIFICATION_ERROR:
896 convertThrowVerificationError(cUnit, vA, vB);
897 break;
buzbee6969d502012-06-15 16:40:31 -0700898
buzbee2cfc6392012-05-07 14:51:40 -0700899#if 0
900
901 case Instruction::MOVE_EXCEPTION: {
902 int exOffset = Thread::ExceptionOffset().Int32Value();
903 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
904#if defined(TARGET_X86)
905 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
906 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
907#else
908 int resetReg = oatAllocTemp(cUnit);
909 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
910 loadConstant(cUnit, resetReg, 0);
911 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
912 storeValue(cUnit, rlDest, rlResult);
913 oatFreeTemp(cUnit, resetReg);
914#endif
915 break;
916 }
917
918 case Instruction::MOVE_RESULT_WIDE:
919 if (mir->optimizationFlags & MIR_INLINED)
920 break; // Nop - combined w/ previous invoke
921 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
922 break;
923
924 case Instruction::MOVE_RESULT:
925 case Instruction::MOVE_RESULT_OBJECT:
926 if (mir->optimizationFlags & MIR_INLINED)
927 break; // Nop - combined w/ previous invoke
928 storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
929 break;
930
931 case Instruction::MONITOR_ENTER:
932 genMonitorEnter(cUnit, mir, rlSrc[0]);
933 break;
934
935 case Instruction::MONITOR_EXIT:
936 genMonitorExit(cUnit, mir, rlSrc[0]);
937 break;
938
939 case Instruction::CHECK_CAST:
940 genCheckCast(cUnit, mir, rlSrc[0]);
941 break;
942
943 case Instruction::INSTANCE_OF:
944 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
945 break;
946
buzbee2cfc6392012-05-07 14:51:40 -0700947 case Instruction::THROW:
948 genThrow(cUnit, mir, rlSrc[0]);
949 break;
950
951 case Instruction::THROW_VERIFICATION_ERROR:
952 genThrowVerificationError(cUnit, mir);
953 break;
954
955 case Instruction::ARRAY_LENGTH:
956 int lenOffset;
957 lenOffset = Array::LengthOffset().Int32Value();
958 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
959 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
960 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
961 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
962 storeValue(cUnit, rlDest, rlResult);
963 break;
964
buzbee2cfc6392012-05-07 14:51:40 -0700965 case Instruction::CONST_CLASS:
966 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
967 break;
968
969 case Instruction::FILL_ARRAY_DATA:
970 genFillArrayData(cUnit, mir, rlSrc[0]);
971 break;
972
973 case Instruction::FILLED_NEW_ARRAY:
974 genFilledNewArray(cUnit, mir, false /* not range */);
975 break;
976
977 case Instruction::FILLED_NEW_ARRAY_RANGE:
978 genFilledNewArray(cUnit, mir, true /* range */);
979 break;
980
981 case Instruction::NEW_ARRAY:
982 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
983 break;
984
985 case Instruction::PACKED_SWITCH:
986 genPackedSwitch(cUnit, mir, rlSrc[0]);
987 break;
988
989 case Instruction::SPARSE_SWITCH:
990 genSparseSwitch(cUnit, mir, rlSrc[0], labelList);
991 break;
992
993 case Instruction::CMPL_FLOAT:
994 case Instruction::CMPG_FLOAT:
995 case Instruction::CMPL_DOUBLE:
996 case Instruction::CMPG_DOUBLE:
997 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
998 break;
999
1000 case Instruction::CMP_LONG:
1001 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
1002 break;
1003
1004 case Instruction::AGET_WIDE:
1005 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
1006 break;
1007 case Instruction::AGET:
1008 case Instruction::AGET_OBJECT:
1009 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
1010 break;
1011 case Instruction::AGET_BOOLEAN:
1012 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
1013 break;
1014 case Instruction::AGET_BYTE:
1015 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
1016 break;
1017 case Instruction::AGET_CHAR:
1018 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
1019 break;
1020 case Instruction::AGET_SHORT:
1021 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
1022 break;
1023 case Instruction::APUT_WIDE:
1024 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
1025 break;
1026 case Instruction::APUT:
1027 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
1028 break;
1029 case Instruction::APUT_OBJECT:
1030 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
1031 break;
1032 case Instruction::APUT_SHORT:
1033 case Instruction::APUT_CHAR:
1034 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
1035 break;
1036 case Instruction::APUT_BYTE:
1037 case Instruction::APUT_BOOLEAN:
1038 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
1039 rlSrc[0], 0);
1040 break;
1041
1042 case Instruction::IGET_OBJECT:
1043 //case Instruction::IGET_OBJECT_VOLATILE:
1044 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
1045 break;
1046
1047 case Instruction::IGET_WIDE:
1048 //case Instruction::IGET_WIDE_VOLATILE:
1049 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
1050 break;
1051
1052 case Instruction::IGET:
1053 //case Instruction::IGET_VOLATILE:
1054 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
1055 break;
1056
1057 case Instruction::IGET_CHAR:
1058 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
1059 break;
1060
1061 case Instruction::IGET_SHORT:
1062 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
1063 break;
1064
1065 case Instruction::IGET_BOOLEAN:
1066 case Instruction::IGET_BYTE:
1067 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
1068 break;
1069
1070 case Instruction::IPUT_WIDE:
1071 //case Instruction::IPUT_WIDE_VOLATILE:
1072 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
1073 break;
1074
1075 case Instruction::IPUT_OBJECT:
1076 //case Instruction::IPUT_OBJECT_VOLATILE:
1077 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
1078 break;
1079
1080 case Instruction::IPUT:
1081 //case Instruction::IPUT_VOLATILE:
1082 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
1083 break;
1084
1085 case Instruction::IPUT_BOOLEAN:
1086 case Instruction::IPUT_BYTE:
1087 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
1088 break;
1089
1090 case Instruction::IPUT_CHAR:
1091 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
1092 break;
1093
1094 case Instruction::IPUT_SHORT:
1095 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
1096 break;
1097
1098 case Instruction::SGET_OBJECT:
1099 genSget(cUnit, mir, rlDest, false, true);
1100 break;
1101 case Instruction::SGET:
1102 case Instruction::SGET_BOOLEAN:
1103 case Instruction::SGET_BYTE:
1104 case Instruction::SGET_CHAR:
1105 case Instruction::SGET_SHORT:
1106 genSget(cUnit, mir, rlDest, false, false);
1107 break;
1108
1109 case Instruction::SGET_WIDE:
1110 genSget(cUnit, mir, rlDest, true, false);
1111 break;
1112
1113 case Instruction::SPUT_OBJECT:
1114 genSput(cUnit, mir, rlSrc[0], false, true);
1115 break;
1116
1117 case Instruction::SPUT:
1118 case Instruction::SPUT_BOOLEAN:
1119 case Instruction::SPUT_BYTE:
1120 case Instruction::SPUT_CHAR:
1121 case Instruction::SPUT_SHORT:
1122 genSput(cUnit, mir, rlSrc[0], false, false);
1123 break;
1124
1125 case Instruction::SPUT_WIDE:
1126 genSput(cUnit, mir, rlSrc[0], true, false);
1127 break;
1128
buzbee2cfc6392012-05-07 14:51:40 -07001129 case Instruction::NEG_INT:
1130 case Instruction::NOT_INT:
1131 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1132 break;
1133
1134 case Instruction::NEG_LONG:
1135 case Instruction::NOT_LONG:
1136 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1137 break;
1138
1139 case Instruction::NEG_FLOAT:
1140 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1141 break;
1142
1143 case Instruction::NEG_DOUBLE:
1144 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1145 break;
1146
1147 case Instruction::INT_TO_LONG:
1148 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
1149 break;
1150
1151 case Instruction::LONG_TO_INT:
1152 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
1153 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
1154 storeValue(cUnit, rlDest, rlSrc[0]);
1155 break;
1156
1157 case Instruction::INT_TO_BYTE:
1158 case Instruction::INT_TO_SHORT:
1159 case Instruction::INT_TO_CHAR:
1160 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
1161 break;
1162
1163 case Instruction::INT_TO_FLOAT:
1164 case Instruction::INT_TO_DOUBLE:
1165 case Instruction::LONG_TO_FLOAT:
1166 case Instruction::LONG_TO_DOUBLE:
1167 case Instruction::FLOAT_TO_INT:
1168 case Instruction::FLOAT_TO_LONG:
1169 case Instruction::FLOAT_TO_DOUBLE:
1170 case Instruction::DOUBLE_TO_INT:
1171 case Instruction::DOUBLE_TO_LONG:
1172 case Instruction::DOUBLE_TO_FLOAT:
1173 genConversion(cUnit, mir);
1174 break;
1175
1176#endif
1177
1178 default:
buzbee32412962012-06-26 16:27:56 -07001179 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001180 res = true;
1181 }
buzbeeb03f4872012-06-11 15:22:11 -07001182 if (objectDefinition) {
1183 setShadowFrameEntry(cUnit, (llvm::Value*)
1184 cUnit->llvmValues.elemList[rlDest.origSReg]);
1185 }
buzbee2cfc6392012-05-07 14:51:40 -07001186 return res;
1187}
1188
1189/* Extended MIR instructions like PHI */
1190void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1191 llvm::BasicBlock* llvmBB)
1192{
1193
1194 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1195 case kMirOpPhi: {
1196 int* incoming = (int*)mir->dalvikInsn.vB;
1197 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1198 llvm::Type* phiType =
1199 llvmTypeFromLocRec(cUnit, rlDest);
1200 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1201 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1202 RegLocation loc;
1203 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001204 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001205 i++;
1206 } else {
1207 loc = oatGetSrc(cUnit, mir, i);
1208 }
1209 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1210 getLLVMBlock(cUnit, incoming[i]));
1211 }
1212 defineValue(cUnit, phi, rlDest.origSReg);
1213 break;
1214 }
1215 case kMirOpCopy: {
1216 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1217 break;
1218 }
1219#if defined(TARGET_ARM)
1220 case kMirOpFusedCmplFloat:
1221 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1222 break;
1223 case kMirOpFusedCmpgFloat:
1224 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1225 break;
1226 case kMirOpFusedCmplDouble:
1227 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1228 break;
1229 case kMirOpFusedCmpgDouble:
1230 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1231 break;
1232 case kMirOpFusedCmpLong:
1233 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1234 break;
1235#endif
1236 default:
1237 break;
1238 }
1239}
1240
1241void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1242{
1243 cUnit->currentDalvikOffset = offset;
1244 llvm::SmallVector<llvm::Value*, 1>arrayRef;
1245 arrayRef.push_back(cUnit->irb->getInt32(offset));
1246 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1247 cUnit->irb->SetDexOffset(node);
1248}
1249
1250// Attach method info as metadata to special intrinsic
1251void setMethodInfo(CompilationUnit* cUnit)
1252{
1253 // We don't want dex offset on this
1254 cUnit->irb->SetDexOffset(NULL);
1255 greenland::IntrinsicHelper::IntrinsicId id;
1256 id = greenland::IntrinsicHelper::MethodInfo;
1257 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1258 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1259 llvm::SmallVector<llvm::Value*, 2> regInfo;
1260 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1261 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1262 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1263 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1264 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1265 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1266 inst->setMetadata("RegInfo", regInfoNode);
1267 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1268 llvm::SmallVector<llvm::Value*, 50> pmap;
1269 for (int i = 0; i < promoSize; i++) {
1270 PromotionMap* p = &cUnit->promotionMap[i];
1271 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1272 ((p->fpReg & 0xff) << 16) |
1273 ((p->coreReg & 0xff) << 8) |
1274 ((p->fpLocation & 0xf) << 4) |
1275 (p->coreLocation & 0xf);
1276 pmap.push_back(cUnit->irb->getInt32(mapData));
1277 }
1278 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1279 inst->setMetadata("PromotionMap", mapNode);
1280 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1281}
1282
1283/* Handle the content in each basic block */
1284bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1285{
1286 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1287 cUnit->irb->SetInsertPoint(llvmBB);
1288 setDexOffset(cUnit, bb->startOffset);
1289
1290 if (bb->blockType == kEntryBlock) {
1291 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001292 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1293 cUnit->numDalvikRegisters, true,
1294 kAllocMisc);
1295 for (int i = 0; i < cUnit->numSSARegs; i++) {
1296 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1297 }
1298 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1299 if (canBeRef[i]) {
1300 cUnit->numShadowFrameEntries++;
1301 }
1302 }
1303 if (cUnit->numShadowFrameEntries > 0) {
1304 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1305 cUnit->numShadowFrameEntries, true,
1306 kAllocMisc);
1307 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1308 if (canBeRef[i]) {
1309 cUnit->shadowMap[j++] = i;
1310 }
1311 }
1312 greenland::IntrinsicHelper::IntrinsicId id =
1313 greenland::IntrinsicHelper::AllocaShadowFrame;
1314 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1315 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1316 cUnit->irb->CreateCall(func, entries);
1317 }
buzbee2cfc6392012-05-07 14:51:40 -07001318 } else if (bb->blockType == kExitBlock) {
1319 /*
1320 * Because of the differences between how MIR/LIR and llvm handle exit
1321 * blocks, we won't explicitly covert them. On the llvm-to-lir
1322 * path, it will need to be regenereated.
1323 */
1324 return false;
buzbee6969d502012-06-15 16:40:31 -07001325 } else if (bb->blockType == kExceptionHandling) {
1326 /*
1327 * Because we're deferring null checking, delete the associated empty
1328 * exception block.
1329 * TODO: add new block type for exception blocks that we generate
1330 * greenland code for.
1331 */
1332 llvmBB->eraseFromParent();
1333 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001334 }
1335
1336 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1337
1338 setDexOffset(cUnit, mir->offset);
1339
1340 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1341 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1342
1343 /* If we're compiling for the debugger, generate an update callout */
1344 if (cUnit->genDebugger) {
1345 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1346 //genDebuggerUpdate(cUnit, mir->offset);
1347 }
1348
1349 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1350 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1351 continue;
1352 }
1353
1354 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1355 NULL /* labelList */);
1356 if (notHandled) {
1357 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1358 mir->offset, dalvikOpcode,
1359 Instruction::Name(dalvikOpcode),
1360 dalvikFormat);
1361 }
1362 }
1363
buzbee6969d502012-06-15 16:40:31 -07001364 if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001365 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1366 }
1367
1368 return false;
1369}
1370
1371llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1372
1373 // Get return type
1374 llvm::Type* ret_type = cUnit->irb->GetJType(cUnit->shorty[0],
1375 greenland::kAccurate);
1376
1377 // Get argument type
1378 std::vector<llvm::Type*> args_type;
1379
1380 // method object
1381 args_type.push_back(cUnit->irb->GetJMethodTy());
1382
1383 // Do we have a "this"?
1384 if ((cUnit->access_flags & kAccStatic) == 0) {
1385 args_type.push_back(cUnit->irb->GetJObjectTy());
1386 }
1387
1388 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
1389 args_type.push_back(cUnit->irb->GetJType(cUnit->shorty[i],
1390 greenland::kAccurate));
1391 }
1392
1393 return llvm::FunctionType::get(ret_type, args_type, false);
1394}
1395
1396bool createFunction(CompilationUnit* cUnit) {
1397 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1398 /* with_signature */ false));
1399 llvm::FunctionType* func_type = getFunctionType(cUnit);
1400
1401 if (func_type == NULL) {
1402 return false;
1403 }
1404
1405 cUnit->func = llvm::Function::Create(func_type,
1406 llvm::Function::ExternalLinkage,
1407 func_name, cUnit->module);
1408
1409 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1410 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1411
1412 arg_iter->setName("method");
1413 ++arg_iter;
1414
1415 int startSReg = cUnit->numRegs;
1416
1417 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1418 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1419 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1420 }
1421
1422 return true;
1423}
1424
1425bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1426{
1427 // Skip the exit block
1428 if (bb->blockType == kExitBlock) {
1429 cUnit->idToBlockMap.Put(bb->id, NULL);
1430 } else {
1431 int offset = bb->startOffset;
1432 bool entryBlock = (bb->blockType == kEntryBlock);
1433 llvm::BasicBlock* llvmBB =
1434 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001435 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001436 cUnit->func);
1437 if (entryBlock) {
1438 cUnit->entryBB = llvmBB;
1439 cUnit->placeholderBB =
1440 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1441 cUnit->func);
1442 }
1443 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1444 }
1445 return false;
1446}
1447
1448
1449/*
1450 * Convert MIR to LLVM_IR
1451 * o For each ssa name, create LLVM named value. Type these
1452 * appropriately, and ignore high half of wide and double operands.
1453 * o For each MIR basic block, create an LLVM basic block.
1454 * o Iterate through the MIR a basic block at a time, setting arguments
1455 * to recovered ssa name.
1456 */
1457void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1458{
1459 initIR(cUnit);
1460 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1461
1462 // Create the function
1463 createFunction(cUnit);
1464
1465 // Create an LLVM basic block for each MIR block in dfs preorder
1466 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1467 kPreOrderDFSTraversal, false /* isIterative */);
1468 /*
1469 * Create an llvm named value for each MIR SSA name. Note: we'll use
1470 * placeholders for all non-argument values (because we haven't seen
1471 * the definition yet).
1472 */
1473 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1474 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1475 arg_iter++; /* Skip path method */
1476 for (int i = 0; i < cUnit->numSSARegs; i++) {
1477 llvm::Value* val;
1478 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1479 if (i < cUnit->numRegs) {
1480 // Skip non-argument _0 names - should never be a use
1481 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1482 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1483 // Handle SSA defs, skipping Method* and compiler temps
1484 if (SRegToVReg(cUnit, i) < 0) {
1485 val = NULL;
1486 } else {
1487 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1488 val->setName(llvmSSAName(cUnit, i));
1489 }
1490 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1491 if (cUnit->regLocation[i].wide) {
1492 // Skip high half of wide values
1493 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1494 i++;
1495 }
1496 } else {
1497 // Recover previously-created argument values
1498 llvm::Value* argVal = arg_iter++;
1499 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
1500 }
1501 }
1502 cUnit->irb->CreateBr(cUnit->placeholderBB);
1503
1504 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1505 kPreOrderDFSTraversal, false /* Iterative */);
1506
1507 cUnit->placeholderBB->eraseFromParent();
1508
1509 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1510
buzbeead8f15e2012-06-18 14:49:45 -07001511 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1512 // Write bitcode to file
1513 std::string errmsg;
1514 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1515 oatReplaceSpecialChars(fname);
1516 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001517 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001518
buzbeead8f15e2012-06-18 14:49:45 -07001519 llvm::OwningPtr<llvm::tool_output_file> out_file(
1520 new llvm::tool_output_file(fname.c_str(), errmsg,
1521 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001522
buzbeead8f15e2012-06-18 14:49:45 -07001523 if (!errmsg.empty()) {
1524 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1525 }
1526
1527 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1528 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07001529 }
buzbee2cfc6392012-05-07 14:51:40 -07001530}
1531
1532RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1533 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001534 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001535 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1536 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07001537 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07001538 if (valName.empty()) {
buzbee4f1181f2012-06-22 13:52:12 -07001539 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
1540 memset(&res, 0, sizeof(res));
1541 res.location = kLocPhysReg;
1542 res.lowReg = oatAllocTemp(cUnit);
1543 res.home = true;
1544 res.sRegLow = INVALID_SREG;
1545 res.origSReg = INVALID_SREG;
1546 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07001547 } else {
1548 DCHECK_EQ(valName[0], 'v');
1549 int baseSReg = INVALID_SREG;
1550 sscanf(valName.c_str(), "v%d_", &baseSReg);
1551 res = cUnit->regLocation[baseSReg];
1552 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07001553 }
1554 } else {
1555 res = it->second;
1556 }
1557 return res;
1558}
1559
1560Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1561{
1562 Instruction::Code res = Instruction::NOP;
1563 if (isWide) {
1564 switch(op) {
1565 case kOpAdd: res = Instruction::ADD_LONG; break;
1566 case kOpSub: res = Instruction::SUB_LONG; break;
1567 case kOpMul: res = Instruction::MUL_LONG; break;
1568 case kOpDiv: res = Instruction::DIV_LONG; break;
1569 case kOpRem: res = Instruction::REM_LONG; break;
1570 case kOpAnd: res = Instruction::AND_LONG; break;
1571 case kOpOr: res = Instruction::OR_LONG; break;
1572 case kOpXor: res = Instruction::XOR_LONG; break;
1573 case kOpLsl: res = Instruction::SHL_LONG; break;
1574 case kOpLsr: res = Instruction::USHR_LONG; break;
1575 case kOpAsr: res = Instruction::SHR_LONG; break;
1576 default: LOG(FATAL) << "Unexpected OpKind " << op;
1577 }
1578 } else if (isConst){
1579 switch(op) {
1580 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
1581 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
1582 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
1583 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
1584 case kOpRem: res = Instruction::REM_INT_LIT16; break;
1585 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
1586 case kOpOr: res = Instruction::OR_INT_LIT16; break;
1587 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
1588 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
1589 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
1590 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
1591 default: LOG(FATAL) << "Unexpected OpKind " << op;
1592 }
1593 } else {
1594 switch(op) {
1595 case kOpAdd: res = Instruction::ADD_INT; break;
1596 case kOpSub: res = Instruction::SUB_INT; break;
1597 case kOpMul: res = Instruction::MUL_INT; break;
1598 case kOpDiv: res = Instruction::DIV_INT; break;
1599 case kOpRem: res = Instruction::REM_INT; break;
1600 case kOpAnd: res = Instruction::AND_INT; break;
1601 case kOpOr: res = Instruction::OR_INT; break;
1602 case kOpXor: res = Instruction::XOR_INT; break;
1603 case kOpLsl: res = Instruction::SHL_INT; break;
1604 case kOpLsr: res = Instruction::USHR_INT; break;
1605 case kOpAsr: res = Instruction::SHR_INT; break;
1606 default: LOG(FATAL) << "Unexpected OpKind " << op;
1607 }
1608 }
1609 return res;
1610}
1611
buzbee4f1181f2012-06-22 13:52:12 -07001612Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
1613{
1614 Instruction::Code res = Instruction::NOP;
1615 if (isWide) {
1616 switch(op) {
1617 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
1618 case kOpSub: res = Instruction::SUB_DOUBLE; break;
1619 case kOpMul: res = Instruction::MUL_DOUBLE; break;
1620 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
1621 case kOpRem: res = Instruction::REM_DOUBLE; break;
1622 default: LOG(FATAL) << "Unexpected OpKind " << op;
1623 }
1624 } else {
1625 switch(op) {
1626 case kOpAdd: res = Instruction::ADD_FLOAT; break;
1627 case kOpSub: res = Instruction::SUB_FLOAT; break;
1628 case kOpMul: res = Instruction::MUL_FLOAT; break;
1629 case kOpDiv: res = Instruction::DIV_FLOAT; break;
1630 case kOpRem: res = Instruction::REM_FLOAT; break;
1631 default: LOG(FATAL) << "Unexpected OpKind " << op;
1632 }
1633 }
1634 return res;
1635}
1636
1637void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1638{
1639 RegLocation rlDest = getLoc(cUnit, inst);
1640 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1641 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
1642 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
1643 if (rlDest.wide) {
1644 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1645 } else {
1646 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1647 }
1648}
1649
buzbee2cfc6392012-05-07 14:51:40 -07001650void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1651{
1652 RegLocation rlDest = getLoc(cUnit, inst);
1653 llvm::Value* lhs = inst->getOperand(0);
buzbee4f1181f2012-06-22 13:52:12 -07001654 // Special-case RSUB
1655 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
1656 if ((op == kOpSub) && (lhsImm != NULL)) {
1657 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
1658 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
1659 lhsImm->getSExtValue());
1660 return;
1661 }
1662 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001663 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1664 llvm::Value* rhs = inst->getOperand(1);
1665 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1666 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
1667 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
1668 } else {
1669 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
1670 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1671 if (rlDest.wide) {
1672 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1673 } else {
1674 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1675 }
1676 }
1677}
1678
1679void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
1680{
1681 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
1682 DCHECK(brInst != NULL);
1683 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
1684 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
1685 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
1686}
1687
1688void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
1689{
1690 // Nop - these have already been processed
1691}
1692
1693void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
1694{
1695 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
1696 llvm::Value* retVal = retInst->getReturnValue();
1697 if (retVal != NULL) {
1698 RegLocation rlSrc = getLoc(cUnit, retVal);
1699 if (rlSrc.wide) {
1700 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
1701 } else {
1702 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
1703 }
1704 }
1705 genExitSequence(cUnit);
1706}
1707
1708ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
1709{
1710 ConditionCode res = kCondAl;
1711 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07001712 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07001713 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
1714 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
1715 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07001716 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07001717 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07001718 default: LOG(FATAL) << "Unexpected llvm condition";
1719 }
1720 return res;
1721}
1722
1723void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
1724{
1725 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
1726 UNIMPLEMENTED(FATAL);
1727}
1728
1729void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
1730 llvm::BranchInst* brInst)
1731{
1732 // Get targets
1733 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
1734 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
1735 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
1736 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
1737 // Get comparison operands
1738 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
1739 ConditionCode cond = getCond(iCmpInst->getPredicate());
1740 llvm::Value* lhs = iCmpInst->getOperand(0);
1741 // Not expecting a constant as 1st operand
1742 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
1743 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1744 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
1745 llvm::Value* rhs = inst->getOperand(1);
1746#if defined(TARGET_MIPS)
1747 // Compare and branch in one shot
1748 (void)taken;
1749 (void)cond;
1750 (void)rhs;
1751 UNIMPLEMENTED(FATAL);
1752#else
1753 //Compare, then branch
1754 // TODO: handle fused CMP_LONG/IF_xxZ case
1755 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1756 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
1757 } else {
1758 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1759 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
1760 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
1761 }
1762 opCondBranch(cUnit, cond, taken);
1763#endif
1764 // Fallthrough
1765 opUnconditionalBranch(cUnit, fallThrough);
1766}
1767
1768void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
1769 llvm::Function* callee)
1770{
1771 UNIMPLEMENTED(FATAL);
1772}
1773
buzbee2cfc6392012-05-07 14:51:40 -07001774void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
1775{
buzbee4f1181f2012-06-22 13:52:12 -07001776 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07001777 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
1778 RegLocation rlDest = getLoc(cUnit, callInst);
1779 if (rlSrc.wide) {
1780 storeValueWide(cUnit, rlDest, rlSrc);
1781 } else {
1782 storeValue(cUnit, rlDest, rlSrc);
1783 }
1784}
1785
1786// Note: Immediate arg is a ConstantInt regardless of result type
1787void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
1788{
buzbee4f1181f2012-06-22 13:52:12 -07001789 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07001790 llvm::ConstantInt* src =
1791 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1792 uint64_t immval = src->getZExtValue();
1793 RegLocation rlDest = getLoc(cUnit, callInst);
1794 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
1795 if (rlDest.wide) {
1796 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
1797 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
1798 storeValueWide(cUnit, rlDest, rlResult);
1799 } else {
1800 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
1801 storeValue(cUnit, rlDest, rlResult);
1802 }
1803}
1804
buzbee6969d502012-06-15 16:40:31 -07001805void cvtConstString(CompilationUnit* cUnit, llvm::CallInst* callInst)
1806{
buzbee4f1181f2012-06-22 13:52:12 -07001807 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee6969d502012-06-15 16:40:31 -07001808 llvm::ConstantInt* stringIdxVal =
1809 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1810 uint32_t stringIdx = stringIdxVal->getZExtValue();
1811 RegLocation rlDest = getLoc(cUnit, callInst);
1812 genConstString(cUnit, stringIdx, rlDest);
1813}
1814
buzbee4f1181f2012-06-22 13:52:12 -07001815void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
1816{
buzbee32412962012-06-26 16:27:56 -07001817 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07001818 llvm::ConstantInt* typeIdxVal =
1819 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1820 uint32_t typeIdx = typeIdxVal->getZExtValue();
1821 RegLocation rlDest = getLoc(cUnit, callInst);
1822 genNewInstance(cUnit, typeIdx, rlDest);
1823}
1824
buzbee32412962012-06-26 16:27:56 -07001825void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
1826{
1827 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
1828 llvm::ConstantInt* info1 =
1829 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1830 llvm::ConstantInt* info2 =
1831 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
1832 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
1833}
1834
1835void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
1836{
1837 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
1838 llvm::Value* src = callInst->getArgOperand(0);
1839 RegLocation rlSrc = getLoc(cUnit, src);
1840 genThrow(cUnit, rlSrc);
1841}
1842
1843void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
1844{
1845 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
1846 int exOffset = Thread::ExceptionOffset().Int32Value();
1847 RegLocation rlDest = getLoc(cUnit, callInst);
1848 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
1849#if defined(TARGET_X86)
1850 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
1851 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
1852#else
1853 int resetReg = oatAllocTemp(cUnit);
1854 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
1855 loadConstant(cUnit, resetReg, 0);
1856 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
1857 oatFreeTemp(cUnit, resetReg);
1858#endif
1859 storeValue(cUnit, rlDest, rlResult);
1860}
1861
buzbee4f1181f2012-06-22 13:52:12 -07001862void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
1863 bool isObject)
1864{
buzbee32412962012-06-26 16:27:56 -07001865 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07001866 llvm::ConstantInt* typeIdxVal =
1867 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1868 uint32_t typeIdx = typeIdxVal->getZExtValue();
1869 RegLocation rlDest = getLoc(cUnit, callInst);
1870 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
1871}
1872
buzbee6969d502012-06-15 16:40:31 -07001873void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
1874 greenland::JType jtype)
1875{
1876 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
1877 kAllocMisc);
1878 if (jtype == greenland::kVoid) {
1879 info->result.location = kLocInvalid;
1880 } else {
1881 info->result = getLoc(cUnit, callInst);
1882 }
1883 llvm::ConstantInt* invokeTypeVal =
1884 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1885 llvm::ConstantInt* methodIndexVal =
1886 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
1887 llvm::ConstantInt* optFlagsVal =
1888 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
1889 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
1890 info->index = methodIndexVal->getZExtValue();
1891 info->optFlags = optFlagsVal->getZExtValue();
1892 info->offset = cUnit->currentDalvikOffset;
1893
1894 // FIXME - rework such that we no longer need isRange
1895 info->isRange = false;
1896
1897 // Count the argument words, and then build argument array.
1898 info->numArgWords = 0;
1899 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
1900 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
1901 info->numArgWords += tLoc.wide ? 2 : 1;
1902 }
1903 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
1904 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
1905 // Now, fill in the location records, synthesizing high loc of wide vals
1906 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07001907 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07001908 if (cUnit->printMe) {
1909 oatDumpRegLoc(info->args[next]);
1910 }
1911 if (info->args[next].wide) {
1912 next++;
1913 // TODO: Might make sense to mark this as an invalid loc
1914 info->args[next].origSReg = info->args[next-1].origSReg+1;
1915 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
1916 }
1917 next++;
1918 }
1919 genInvoke(cUnit, info);
1920}
1921
buzbeead8f15e2012-06-18 14:49:45 -07001922/* Look up the RegLocation associated with a Value. Must already be defined */
1923RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
1924{
1925 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1926 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
1927 return it->second;
1928}
1929
buzbee2cfc6392012-05-07 14:51:40 -07001930bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
1931{
1932 bool isEntry = (bb == &cUnit->func->getEntryBlock());
1933 // Define the starting label
1934 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
1935 // Extract the starting offset from the block's name
1936 if (!isEntry) {
1937 const char* blockName = bb->getName().str().c_str();
1938 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07001939 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07001940 }
1941 // Set the label kind
1942 blockLabel->opcode = kPseudoNormalBlockLabel;
1943 // Insert the label
1944 oatAppendLIR(cUnit, blockLabel);
1945
1946 // Free temp registers and reset redundant store tracking */
1947 oatResetRegPool(cUnit);
1948 oatResetDefTracking(cUnit);
1949
1950 //TODO: restore oat incoming liveness optimization
1951 oatClobberAllRegs(cUnit);
1952
buzbee6969d502012-06-15 16:40:31 -07001953 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07001954
1955 if (isEntry) {
1956 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07001957 RegLocation* argLocs = (RegLocation*)
1958 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
1959 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
1960 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
1961 for (unsigned i = 0; it != it_end; ++it) {
1962 llvm::Value* val = it;
1963 argLocs[i++] = valToLoc(cUnit, val);
1964 llvm::Type* ty = val->getType();
1965 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
1966 argLocs[i++].sRegLow = INVALID_SREG;
1967 }
1968 }
1969 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07001970 }
1971
1972 // Visit all of the instructions in the block
1973 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
1974 llvm::Instruction* inst = it;
1975 llvm::BasicBlock::iterator nextIt = ++it;
1976 // Extract the Dalvik offset from the instruction
1977 uint32_t opcode = inst->getOpcode();
1978 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
1979 if (dexOffsetNode != NULL) {
1980 llvm::ConstantInt* dexOffsetValue =
1981 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
1982 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
1983 }
1984
buzbee6969d502012-06-15 16:40:31 -07001985 oatResetRegPool(cUnit);
1986 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
1987 oatClobberAllRegs(cUnit);
1988 }
1989
1990 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
1991 oatResetDefTracking(cUnit);
1992 }
1993
1994#ifndef NDEBUG
1995 /* Reset temp tracking sanity check */
1996 cUnit->liveSReg = INVALID_SREG;
1997#endif
1998
1999 LIR* boundaryLIR;
2000 const char* instStr = "boundary";
2001 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2002 (intptr_t) instStr);
2003 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2004
2005 /* Remember the first LIR for thisl block*/
2006 if (headLIR == NULL) {
2007 headLIR = boundaryLIR;
2008 headLIR->defMask = ENCODE_ALL;
2009 }
2010
buzbee2cfc6392012-05-07 14:51:40 -07002011 switch(opcode) {
2012
2013 case llvm::Instruction::ICmp: {
2014 llvm::Instruction* nextInst = nextIt;
2015 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2016 if (brInst != NULL /* and... */) {
2017 cvtICmpBr(cUnit, inst, brInst);
2018 ++it;
2019 } else {
2020 cvtICmp(cUnit, inst);
2021 }
2022 }
2023 break;
2024
2025 case llvm::Instruction::Call: {
2026 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2027 llvm::Function* callee = callInst->getCalledFunction();
2028 greenland::IntrinsicHelper::IntrinsicId id =
2029 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2030 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002031 case greenland::IntrinsicHelper::AllocaShadowFrame:
2032 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002033 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002034 // Ignore shadow frame stuff for quick compiler
2035 break;
buzbee2cfc6392012-05-07 14:51:40 -07002036 case greenland::IntrinsicHelper::CopyInt:
2037 case greenland::IntrinsicHelper::CopyObj:
2038 case greenland::IntrinsicHelper::CopyFloat:
2039 case greenland::IntrinsicHelper::CopyLong:
2040 case greenland::IntrinsicHelper::CopyDouble:
2041 cvtCopy(cUnit, callInst);
2042 break;
2043 case greenland::IntrinsicHelper::ConstInt:
2044 case greenland::IntrinsicHelper::ConstObj:
2045 case greenland::IntrinsicHelper::ConstLong:
2046 case greenland::IntrinsicHelper::ConstFloat:
2047 case greenland::IntrinsicHelper::ConstDouble:
2048 cvtConst(cUnit, callInst);
2049 break;
buzbee4f1181f2012-06-22 13:52:12 -07002050 case greenland::IntrinsicHelper::DivInt:
2051 case greenland::IntrinsicHelper::DivLong:
2052 cvtBinOp(cUnit, kOpDiv, inst);
2053 break;
2054 case greenland::IntrinsicHelper::RemInt:
2055 case greenland::IntrinsicHelper::RemLong:
2056 cvtBinOp(cUnit, kOpRem, inst);
2057 break;
buzbee2cfc6392012-05-07 14:51:40 -07002058 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002059 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002060 break;
2061 case greenland::IntrinsicHelper::CheckSuspend:
2062 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2063 break;
buzbee6969d502012-06-15 16:40:31 -07002064 case greenland::IntrinsicHelper::HLInvokeInt:
2065 cvtInvoke(cUnit, callInst, greenland::kInt);
2066 break;
buzbee4f1181f2012-06-22 13:52:12 -07002067 case greenland::IntrinsicHelper::HLInvokeObj:
2068 cvtInvoke(cUnit, callInst, greenland::kObject);
2069 break;
buzbee6969d502012-06-15 16:40:31 -07002070 case greenland::IntrinsicHelper::HLInvokeVoid:
2071 cvtInvoke(cUnit, callInst, greenland::kVoid);
2072 break;
2073 case greenland::IntrinsicHelper::ConstString:
2074 cvtConstString(cUnit, callInst);
2075 break;
buzbee4f1181f2012-06-22 13:52:12 -07002076 case greenland::IntrinsicHelper::NewInstance:
2077 cvtNewInstance(cUnit, callInst);
2078 break;
2079 case greenland::IntrinsicHelper::SgetObj:
2080 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2081 break;
buzbee32412962012-06-26 16:27:56 -07002082 case greenland::IntrinsicHelper::GetException:
2083 cvtMoveException(cUnit, callInst);
2084 break;
2085 case greenland::IntrinsicHelper::Throw:
2086 cvtThrow(cUnit, callInst);
2087 break;
2088 case greenland::IntrinsicHelper::ThrowVerificationError:
2089 cvtThrow(cUnit, callInst);
2090 break;
buzbee2cfc6392012-05-07 14:51:40 -07002091 case greenland::IntrinsicHelper::UnknownId:
2092 cvtCall(cUnit, callInst, callee);
2093 break;
2094 default:
2095 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
2096 << cUnit->intrinsic_helper->GetName(id);
2097 }
2098 }
2099 break;
2100
2101 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
2102 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
2103 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
2104 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
2105 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
2106 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
2107 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
2108 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
2109 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
2110 case llvm::Instruction::Shl: cvtBinOp(cUnit, kOpLsl, inst); break;
2111 case llvm::Instruction::LShr: cvtBinOp(cUnit, kOpLsr, inst); break;
2112 case llvm::Instruction::AShr: cvtBinOp(cUnit, kOpAsr, inst); break;
2113 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
2114 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07002115 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
2116 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
2117 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
2118 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
2119 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07002120
buzbee32412962012-06-26 16:27:56 -07002121 case llvm::Instruction::Unreachable:
2122 break; // FIXME: can we really ignore these?
2123
buzbee2cfc6392012-05-07 14:51:40 -07002124 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07002125 case llvm::Instruction::Trunc:
2126 case llvm::Instruction::ZExt:
2127 case llvm::Instruction::SExt:
2128 case llvm::Instruction::FPToUI:
2129 case llvm::Instruction::FPToSI:
2130 case llvm::Instruction::UIToFP:
2131 case llvm::Instruction::SIToFP:
2132 case llvm::Instruction::FPTrunc:
2133 case llvm::Instruction::FPExt:
2134 case llvm::Instruction::PtrToInt:
2135 case llvm::Instruction::IntToPtr:
2136 case llvm::Instruction::Switch:
2137 case llvm::Instruction::FCmp:
2138 UNIMPLEMENTED(FATAL) << "Unimplemented llvm opcode: " << opcode; break;
buzbee4f1181f2012-06-22 13:52:12 -07002139 break;
buzbee2cfc6392012-05-07 14:51:40 -07002140
2141 case llvm::Instruction::URem:
2142 case llvm::Instruction::UDiv:
2143 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07002144 case llvm::Instruction::Alloca:
2145 case llvm::Instruction::GetElementPtr:
2146 case llvm::Instruction::Fence:
2147 case llvm::Instruction::AtomicCmpXchg:
2148 case llvm::Instruction::AtomicRMW:
2149 case llvm::Instruction::BitCast:
2150 case llvm::Instruction::VAArg:
2151 case llvm::Instruction::Select:
2152 case llvm::Instruction::UserOp1:
2153 case llvm::Instruction::UserOp2:
2154 case llvm::Instruction::ExtractElement:
2155 case llvm::Instruction::InsertElement:
2156 case llvm::Instruction::ShuffleVector:
2157 case llvm::Instruction::ExtractValue:
2158 case llvm::Instruction::InsertValue:
2159 case llvm::Instruction::LandingPad:
2160 case llvm::Instruction::IndirectBr:
2161 case llvm::Instruction::Load:
2162 case llvm::Instruction::Store:
2163 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
2164
2165 default:
2166 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
2167 }
2168 }
buzbee6969d502012-06-15 16:40:31 -07002169
2170 if (headLIR != NULL) {
2171 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
2172 }
buzbee2cfc6392012-05-07 14:51:40 -07002173 return false;
2174}
2175
2176/*
2177 * Convert LLVM_IR to MIR:
2178 * o Iterate through the LLVM_IR and construct a graph using
2179 * standard MIR building blocks.
2180 * o Perform a basic-block optimization pass to remove unnecessary
2181 * store/load sequences.
2182 * o Convert the LLVM Value operands into RegLocations where applicable.
2183 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
2184 * o Perform register promotion
2185 * o Iterate through the graph a basic block at a time, generating
2186 * LIR.
2187 * o Assemble LIR as usual.
2188 * o Profit.
2189 */
2190void oatMethodBitcode2LIR(CompilationUnit* cUnit)
2191{
buzbeead8f15e2012-06-18 14:49:45 -07002192 llvm::Function* func = cUnit->func;
2193 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07002194 // Allocate a list for LIR basic block labels
2195 cUnit->blockLabelList =
2196 (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
2197 LIR* labelList = (LIR*)cUnit->blockLabelList;
2198 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002199 for (llvm::Function::iterator i = func->begin(),
2200 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07002201 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
2202 &labelList[nextLabel++]);
2203 }
buzbeead8f15e2012-06-18 14:49:45 -07002204
2205 /*
2206 * Keep honest - clear regLocations, Value => RegLocation,
2207 * promotion map and VmapTables.
2208 */
2209 cUnit->locMap.clear(); // Start fresh
2210 cUnit->regLocation = NULL;
2211 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
2212 i++) {
2213 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
2214 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
2215 }
2216 cUnit->coreSpillMask = 0;
2217 cUnit->numCoreSpills = 0;
2218 cUnit->fpSpillMask = 0;
2219 cUnit->numFPSpills = 0;
2220 cUnit->coreVmapTable.clear();
2221 cUnit->fpVmapTable.clear();
2222 oatAdjustSpillMask(cUnit);
2223 cUnit->frameSize = oatComputeFrameSize(cUnit);
2224
2225 /*
2226 * At this point, we've lost all knowledge of register promotion.
2227 * Rebuild that info from the MethodInfo intrinsic (if it
2228 * exists - not required for correctness).
2229 */
2230 // TODO: find and recover MethodInfo.
2231
2232 // Create RegLocations for arguments
2233 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2234 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2235 for (; it != it_end; ++it) {
2236 llvm::Value* val = it;
2237 createLocFromValue(cUnit, val);
2238 }
2239 // Create RegLocations for all non-argument defintions
2240 for (llvm::inst_iterator i = llvm::inst_begin(func),
2241 e = llvm::inst_end(func); i != e; ++i) {
2242 llvm::Value* val = &*i;
2243 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
2244 createLocFromValue(cUnit, val);
2245 }
2246 }
2247
buzbee2cfc6392012-05-07 14:51:40 -07002248 // Walk the blocks, generating code.
2249 for (llvm::Function::iterator i = cUnit->func->begin(),
2250 e = cUnit->func->end(); i != e; ++i) {
2251 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
2252 }
2253
2254 handleSuspendLaunchpads(cUnit);
2255
2256 handleThrowLaunchpads(cUnit);
2257
2258 handleIntrinsicLaunchpads(cUnit);
2259
2260 freeIR(cUnit);
2261}
2262
2263
2264} // namespace art
2265
2266#endif // ART_USE_QUICK_COMPILER