blob: 1c4fdf4640f6ee4786cd212c590a416bce8d1791 [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
206void emitSuspendCheck(CompilationUnit* cUnit)
207{
208 greenland::IntrinsicHelper::IntrinsicId id =
209 greenland::IntrinsicHelper::CheckSuspend;
210 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
211 cUnit->irb->CreateCall(intr);
212}
213
214llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
215 llvm::Value* src1, llvm::Value* src2)
216{
217 llvm::Value* res = NULL;
218 switch(cc) {
219 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
220 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
221 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
222 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
223 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
224 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
225 default: LOG(FATAL) << "Unexpected cc value " << cc;
226 }
227 return res;
228}
229
230void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
231 ConditionCode cc, RegLocation rlSrc1,
232 RegLocation rlSrc2)
233{
234 if (bb->taken->startOffset <= mir->offset) {
235 emitSuspendCheck(cUnit);
236 }
237 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
238 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
239 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
240 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
241 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
242 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700243 // Don't redo the fallthrough branch in the BB driver
244 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700245}
246
247void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
248 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
249{
250 if (bb->taken->startOffset <= mir->offset) {
251 emitSuspendCheck(cUnit);
252 }
253 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
254 llvm::Value* src2;
255 if (rlSrc1.ref) {
256 src2 = cUnit->irb->GetJNull();
257 } else {
258 src2 = cUnit->irb->getInt32(0);
259 }
260 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
261 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
262 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
263 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700264 // Don't redo the fallthrough branch in the BB driver
265 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700266}
267
268llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
269 llvm::Value* src1, llvm::Value* src2)
270{
271 greenland::IntrinsicHelper::IntrinsicId id;
272 if (isLong) {
273 if (isDiv) {
274 id = greenland::IntrinsicHelper::DivLong;
275 } else {
276 id = greenland::IntrinsicHelper::RemLong;
277 }
278 } else if (isDiv) {
279 id = greenland::IntrinsicHelper::DivInt;
280 } else {
281 id = greenland::IntrinsicHelper::RemInt;
282 }
283 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
284 llvm::SmallVector<llvm::Value*, 2>args;
285 args.push_back(src1);
286 args.push_back(src2);
287 return cUnit->irb->CreateCall(intr, args);
288}
289
290llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
291 llvm::Value* src1, llvm::Value* src2)
292{
293 llvm::Value* res = NULL;
294 switch(op) {
295 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
296 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700297 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700298 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
299 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
300 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
301 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
302 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
303 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700304 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
305 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
306 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700307 default:
308 LOG(FATAL) << "Invalid op " << op;
309 }
310 return res;
311}
312
313void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
314 RegLocation rlSrc1, RegLocation rlSrc2)
315{
316 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
317 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
318 llvm::Value* res = NULL;
buzbee4f1181f2012-06-22 13:52:12 -0700319LOG(INFO) << "in convertFPArithOp";
buzbee2cfc6392012-05-07 14:51:40 -0700320 switch(op) {
321 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
322 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
323 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
324 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
325 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
326 default:
327 LOG(FATAL) << "Invalid op " << op;
328 }
329 defineValue(cUnit, res, rlDest.origSReg);
330}
331
buzbee4f1181f2012-06-22 13:52:12 -0700332void convertShift(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
333 RegLocation rlSrc1, RegLocation rlSrc2)
334{
335 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
336 llvm::Value* src2a = getLLVMValue(cUnit, rlSrc2.origSReg);
337 llvm::Value* src2b;
338 // Limit shift counnt to 63 for long and 31 for int
339 if (rlDest.wide) {
340 // Note: creates 2 unnamed temps
341 llvm::Value* t1 = cUnit->irb->CreateAnd(src2a, 0x3f);
342 src2b = cUnit->irb->CreateZExt(t1, cUnit->irb->getInt64Ty());
343 } else {
344 // Note: creates 1 unnamed temp
345 src2b = cUnit->irb->CreateAnd(src2a, 0x1f);
346 }
347 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2b);
348 defineValue(cUnit, res, rlDest.origSReg);
349}
350
buzbee2cfc6392012-05-07 14:51:40 -0700351void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
352 RegLocation rlSrc1, RegLocation rlSrc2)
353{
354 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
355 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
356 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
357 defineValue(cUnit, res, rlDest.origSReg);
358}
359
buzbeeb03f4872012-06-11 15:22:11 -0700360void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
361{
362 int index = -1;
363 DCHECK(newVal != NULL);
364 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
365 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
366 if (cUnit->shadowMap[i] == vReg) {
367 index = i;
368 break;
369 }
370 }
Elliott Hughes74847412012-06-20 18:10:21 -0700371 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700372 greenland::IntrinsicHelper::IntrinsicId id =
373 greenland::IntrinsicHelper::SetShadowFrameEntry;
374 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
375 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
376 llvm::Value* args[] = { newVal, tableSlot };
377 cUnit->irb->CreateCall(func, args);
378}
379
buzbee2cfc6392012-05-07 14:51:40 -0700380void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
381 RegLocation rlSrc1, int32_t imm)
382{
383 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
384 llvm::Value* src2 = cUnit->irb->getInt32(imm);
385 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
386 defineValue(cUnit, res, rlDest.origSReg);
387}
388
buzbee6969d502012-06-15 16:40:31 -0700389void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
390 InvokeType invokeType, bool isRange)
391{
392 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
393 llvm::SmallVector<llvm::Value*, 10> args;
394 // Insert the invokeType
395 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
396 // Insert the method_idx
397 args.push_back(cUnit->irb->getInt32(info->index));
398 // Insert the optimization flags
399 args.push_back(cUnit->irb->getInt32(info->optFlags));
400 // Now, insert the actual arguments
401 if (cUnit->printMe) {
402 LOG(INFO) << "Building Invoke info";
403 }
404 for (int i = 0; i < info->numArgWords;) {
405 if (cUnit->printMe) {
406 oatDumpRegLoc(info->args[i]);
407 }
408 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
409 args.push_back(val);
410 i += info->args[i].wide ? 2 : 1;
411 }
412 /*
413 * Choose the invoke return type based on actual usage. Note: may
414 * be different than shorty. For example, if a function return value
415 * is not used, we'll treat this as a void invoke.
416 */
417 greenland::IntrinsicHelper::IntrinsicId id;
418 if (info->result.location == kLocInvalid) {
419 id = greenland::IntrinsicHelper::HLInvokeVoid;
420 } else {
421 if (info->result.wide) {
422 if (info->result.fp) {
423 id = greenland::IntrinsicHelper::HLInvokeDouble;
424 } else {
425 id = greenland::IntrinsicHelper::HLInvokeFloat;
426 }
427 } else if (info->result.ref) {
428 id = greenland::IntrinsicHelper::HLInvokeObj;
429 } else if (info->result.fp) {
430 id = greenland::IntrinsicHelper::HLInvokeFloat;
431 } else {
432 id = greenland::IntrinsicHelper::HLInvokeInt;
433 }
434 }
435 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
436 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
437 if (info->result.location != kLocInvalid) {
438 defineValue(cUnit, res, info->result.origSReg);
439 }
440}
441
442void convertConstString(CompilationUnit* cUnit, BasicBlock* bb,
443 uint32_t string_idx, RegLocation rlDest)
444{
445 greenland::IntrinsicHelper::IntrinsicId id;
446 id = greenland::IntrinsicHelper::ConstString;
447 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
448 llvm::Value* index = cUnit->irb->getInt32(string_idx);
449 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
450 defineValue(cUnit, res, rlDest.origSReg);
451}
452
buzbee4f1181f2012-06-22 13:52:12 -0700453void convertNewInstance(CompilationUnit* cUnit, BasicBlock* bb,
454 uint32_t type_idx, RegLocation rlDest)
455{
456 greenland::IntrinsicHelper::IntrinsicId id;
457 id = greenland::IntrinsicHelper::NewInstance;
458 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
459 llvm::Value* index = cUnit->irb->getInt32(type_idx);
460 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
461 defineValue(cUnit, res, rlDest.origSReg);
462}
463
buzbee2cfc6392012-05-07 14:51:40 -0700464/*
465 * Target-independent code generation. Use only high-level
466 * load/store utilities here, or target-dependent genXX() handlers
467 * when necessary.
468 */
469bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
470 llvm::BasicBlock* llvmBB, LIR* labelList)
471{
472 bool res = false; // Assume success
473 RegLocation rlSrc[3];
474 RegLocation rlDest = badLoc;
475 RegLocation rlResult = badLoc;
476 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700477 uint32_t vB = mir->dalvikInsn.vB;
478 uint32_t vC = mir->dalvikInsn.vC;
479
buzbeeb03f4872012-06-11 15:22:11 -0700480 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700481
482 /* Prep Src and Dest locations */
483 int nextSreg = 0;
484 int nextLoc = 0;
485 int attrs = oatDataFlowAttributes[opcode];
486 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
487 if (attrs & DF_UA) {
488 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700489 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700490 nextSreg+= 2;
491 } else {
492 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
493 nextSreg++;
494 }
495 }
496 if (attrs & DF_UB) {
497 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700498 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700499 nextSreg+= 2;
500 } else {
501 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
502 nextSreg++;
503 }
504 }
505 if (attrs & DF_UC) {
506 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700507 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700508 } else {
509 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
510 }
511 }
512 if (attrs & DF_DA) {
513 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700514 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700515 } else {
buzbee15bf9802012-06-12 17:49:27 -0700516 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700517 if (rlDest.ref) {
518 objectDefinition = true;
519 }
buzbee2cfc6392012-05-07 14:51:40 -0700520 }
521 }
522
523 switch (opcode) {
524 case Instruction::NOP:
525 break;
526
527 case Instruction::MOVE:
528 case Instruction::MOVE_OBJECT:
529 case Instruction::MOVE_16:
530 case Instruction::MOVE_OBJECT_16:
531 case Instruction::MOVE_FROM16:
532 case Instruction::MOVE_WIDE:
533 case Instruction::MOVE_WIDE_16:
534 case Instruction::MOVE_WIDE_FROM16: {
535 /*
536 * Moves/copies are meaningless in pure SSA register form,
537 * but we need to preserve them for the conversion back into
538 * MIR (at least until we stop using the Dalvik register maps).
539 * Insert a dummy intrinsic copy call, which will be recognized
540 * by the quick path and removed by the portable path.
541 */
542 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
543 llvm::Value* res = emitCopy(cUnit, src, rlDest);
544 defineValue(cUnit, res, rlDest.origSReg);
545 }
546 break;
547
548 case Instruction::CONST:
549 case Instruction::CONST_4:
550 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700551 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700552 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
553 defineValue(cUnit, res, rlDest.origSReg);
554 }
555 break;
556
557 case Instruction::CONST_WIDE_16:
558 case Instruction::CONST_WIDE_32: {
buzbee6969d502012-06-15 16:40:31 -0700559 llvm::Constant* immValue = cUnit->irb->GetJLong(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700560 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
561 defineValue(cUnit, res, rlDest.origSReg);
562 }
563 break;
564
565 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700566 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700567 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
568 defineValue(cUnit, res, rlDest.origSReg);
569 }
570 break;
571
572 case Instruction::CONST_WIDE: {
573 llvm::Constant* immValue =
574 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
575 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
576 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700577 }
578 break;
buzbee2cfc6392012-05-07 14:51:40 -0700579 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700580 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700581 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
582 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
583 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700584 }
585 break;
586
587 case Instruction::SGET_OBJECT: {
588 llvm::Constant* fieldIdx = cUnit->irb->GetJInt(vB);
589 llvm::Value* res = emitSget(cUnit, greenland::IntrinsicHelper::SgetObj,
590 fieldIdx, rlDest);
591 defineValue(cUnit, res, rlDest.origSReg);
592 }
593 break;
buzbee2cfc6392012-05-07 14:51:40 -0700594
595 case Instruction::RETURN_WIDE:
596 case Instruction::RETURN:
597 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700598 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700599 emitSuspendCheck(cUnit);
600 }
buzbeeb03f4872012-06-11 15:22:11 -0700601 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700602 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
603 bb->hasReturn = true;
604 }
605 break;
606
607 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -0700608 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700609 emitSuspendCheck(cUnit);
610 }
buzbeeb03f4872012-06-11 15:22:11 -0700611 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700612 cUnit->irb->CreateRetVoid();
613 bb->hasReturn = true;
614 }
615 break;
616
617 case Instruction::IF_EQ:
618 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
619 break;
620 case Instruction::IF_NE:
621 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
622 break;
623 case Instruction::IF_LT:
624 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
625 break;
626 case Instruction::IF_GE:
627 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
628 break;
629 case Instruction::IF_GT:
630 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
631 break;
632 case Instruction::IF_LE:
633 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
634 break;
635 case Instruction::IF_EQZ:
636 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
637 break;
638 case Instruction::IF_NEZ:
639 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
640 break;
641 case Instruction::IF_LTZ:
642 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
643 break;
644 case Instruction::IF_GEZ:
645 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
646 break;
647 case Instruction::IF_GTZ:
648 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
649 break;
650 case Instruction::IF_LEZ:
651 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
652 break;
653
654 case Instruction::GOTO:
655 case Instruction::GOTO_16:
656 case Instruction::GOTO_32: {
657 if (bb->taken->startOffset <= bb->startOffset) {
658 emitSuspendCheck(cUnit);
659 }
660 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
661 }
662 break;
663
664 case Instruction::ADD_LONG:
665 case Instruction::ADD_LONG_2ADDR:
666 case Instruction::ADD_INT:
667 case Instruction::ADD_INT_2ADDR:
668 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
669 break;
670 case Instruction::SUB_LONG:
671 case Instruction::SUB_LONG_2ADDR:
672 case Instruction::SUB_INT:
673 case Instruction::SUB_INT_2ADDR:
674 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
675 break;
676 case Instruction::MUL_LONG:
677 case Instruction::MUL_LONG_2ADDR:
678 case Instruction::MUL_INT:
679 case Instruction::MUL_INT_2ADDR:
680 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
681 break;
682 case Instruction::DIV_LONG:
683 case Instruction::DIV_LONG_2ADDR:
684 case Instruction::DIV_INT:
685 case Instruction::DIV_INT_2ADDR:
686 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
687 break;
688 case Instruction::REM_LONG:
689 case Instruction::REM_LONG_2ADDR:
690 case Instruction::REM_INT:
691 case Instruction::REM_INT_2ADDR:
692 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
693 break;
694 case Instruction::AND_LONG:
695 case Instruction::AND_LONG_2ADDR:
696 case Instruction::AND_INT:
697 case Instruction::AND_INT_2ADDR:
698 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
699 break;
700 case Instruction::OR_LONG:
701 case Instruction::OR_LONG_2ADDR:
702 case Instruction::OR_INT:
703 case Instruction::OR_INT_2ADDR:
704 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
705 break;
706 case Instruction::XOR_LONG:
707 case Instruction::XOR_LONG_2ADDR:
708 case Instruction::XOR_INT:
709 case Instruction::XOR_INT_2ADDR:
710 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
711 break;
712 case Instruction::SHL_LONG:
713 case Instruction::SHL_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700714 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
715 break;
buzbee2cfc6392012-05-07 14:51:40 -0700716 case Instruction::SHL_INT:
717 case Instruction::SHL_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700718 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700719 break;
720 case Instruction::SHR_LONG:
721 case Instruction::SHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700722 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
723 break;
buzbee2cfc6392012-05-07 14:51:40 -0700724 case Instruction::SHR_INT:
725 case Instruction::SHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700726 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700727 break;
728 case Instruction::USHR_LONG:
729 case Instruction::USHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700730 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
731 break;
buzbee2cfc6392012-05-07 14:51:40 -0700732 case Instruction::USHR_INT:
733 case Instruction::USHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700734 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700735 break;
736
737 case Instruction::ADD_INT_LIT16:
738 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700739 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700740 break;
741 case Instruction::RSUB_INT:
742 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700743 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700744 break;
745 case Instruction::MUL_INT_LIT16:
746 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700747 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700748 break;
749 case Instruction::DIV_INT_LIT16:
750 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700751 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700752 break;
753 case Instruction::REM_INT_LIT16:
754 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700755 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700756 break;
757 case Instruction::AND_INT_LIT16:
758 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700759 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700760 break;
761 case Instruction::OR_INT_LIT16:
762 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700763 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700764 break;
765 case Instruction::XOR_INT_LIT16:
766 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700767 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700768 break;
769 case Instruction::SHL_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -0700770 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -0700771 break;
772 case Instruction::SHR_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -0700773 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -0700774 break;
775 case Instruction::USHR_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -0700776 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -0700777 break;
778
779 case Instruction::ADD_FLOAT:
780 case Instruction::ADD_FLOAT_2ADDR:
781 case Instruction::ADD_DOUBLE:
782 case Instruction::ADD_DOUBLE_2ADDR:
783 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
784 break;
785
786 case Instruction::SUB_FLOAT:
787 case Instruction::SUB_FLOAT_2ADDR:
788 case Instruction::SUB_DOUBLE:
789 case Instruction::SUB_DOUBLE_2ADDR:
790 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
791 break;
792
793 case Instruction::MUL_FLOAT:
794 case Instruction::MUL_FLOAT_2ADDR:
795 case Instruction::MUL_DOUBLE:
796 case Instruction::MUL_DOUBLE_2ADDR:
797 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
798 break;
799
800 case Instruction::DIV_FLOAT:
801 case Instruction::DIV_FLOAT_2ADDR:
802 case Instruction::DIV_DOUBLE:
803 case Instruction::DIV_DOUBLE_2ADDR:
804 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
805 break;
806
807 case Instruction::REM_FLOAT:
808 case Instruction::REM_FLOAT_2ADDR:
809 case Instruction::REM_DOUBLE:
810 case Instruction::REM_DOUBLE_2ADDR:
811 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
812 break;
813
buzbee6969d502012-06-15 16:40:31 -0700814 case Instruction::INVOKE_STATIC:
815 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/);
816 break;
817 case Instruction::INVOKE_STATIC_RANGE:
818 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/);
819 break;
820
821 case Instruction::INVOKE_DIRECT:
822 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/);
823 break;
824 case Instruction::INVOKE_DIRECT_RANGE:
825 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/);
826 break;
827
828 case Instruction::INVOKE_VIRTUAL:
829 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/);
830 break;
831 case Instruction::INVOKE_VIRTUAL_RANGE:
832 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/);
833 break;
834
835 case Instruction::INVOKE_SUPER:
836 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/);
837 break;
838 case Instruction::INVOKE_SUPER_RANGE:
839 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/);
840 break;
841
842 case Instruction::INVOKE_INTERFACE:
843 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/);
844 break;
845 case Instruction::INVOKE_INTERFACE_RANGE:
846 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/);
847 break;
848
849 case Instruction::CONST_STRING:
850 case Instruction::CONST_STRING_JUMBO:
851 convertConstString(cUnit, bb, vB, rlDest);
852 break;
853
buzbee4f1181f2012-06-22 13:52:12 -0700854 case Instruction::NEW_INSTANCE:
855 convertNewInstance(cUnit, bb, vB, rlDest);
856 break;
857
buzbee6969d502012-06-15 16:40:31 -0700858
buzbee2cfc6392012-05-07 14:51:40 -0700859#if 0
860
861 case Instruction::MOVE_EXCEPTION: {
862 int exOffset = Thread::ExceptionOffset().Int32Value();
863 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
864#if defined(TARGET_X86)
865 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
866 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
867#else
868 int resetReg = oatAllocTemp(cUnit);
869 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
870 loadConstant(cUnit, resetReg, 0);
871 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
872 storeValue(cUnit, rlDest, rlResult);
873 oatFreeTemp(cUnit, resetReg);
874#endif
875 break;
876 }
877
878 case Instruction::MOVE_RESULT_WIDE:
879 if (mir->optimizationFlags & MIR_INLINED)
880 break; // Nop - combined w/ previous invoke
881 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
882 break;
883
884 case Instruction::MOVE_RESULT:
885 case Instruction::MOVE_RESULT_OBJECT:
886 if (mir->optimizationFlags & MIR_INLINED)
887 break; // Nop - combined w/ previous invoke
888 storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
889 break;
890
891 case Instruction::MONITOR_ENTER:
892 genMonitorEnter(cUnit, mir, rlSrc[0]);
893 break;
894
895 case Instruction::MONITOR_EXIT:
896 genMonitorExit(cUnit, mir, rlSrc[0]);
897 break;
898
899 case Instruction::CHECK_CAST:
900 genCheckCast(cUnit, mir, rlSrc[0]);
901 break;
902
903 case Instruction::INSTANCE_OF:
904 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
905 break;
906
buzbee2cfc6392012-05-07 14:51:40 -0700907 case Instruction::THROW:
908 genThrow(cUnit, mir, rlSrc[0]);
909 break;
910
911 case Instruction::THROW_VERIFICATION_ERROR:
912 genThrowVerificationError(cUnit, mir);
913 break;
914
915 case Instruction::ARRAY_LENGTH:
916 int lenOffset;
917 lenOffset = Array::LengthOffset().Int32Value();
918 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
919 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
920 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
921 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
922 storeValue(cUnit, rlDest, rlResult);
923 break;
924
buzbee2cfc6392012-05-07 14:51:40 -0700925 case Instruction::CONST_CLASS:
926 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
927 break;
928
929 case Instruction::FILL_ARRAY_DATA:
930 genFillArrayData(cUnit, mir, rlSrc[0]);
931 break;
932
933 case Instruction::FILLED_NEW_ARRAY:
934 genFilledNewArray(cUnit, mir, false /* not range */);
935 break;
936
937 case Instruction::FILLED_NEW_ARRAY_RANGE:
938 genFilledNewArray(cUnit, mir, true /* range */);
939 break;
940
941 case Instruction::NEW_ARRAY:
942 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
943 break;
944
945 case Instruction::PACKED_SWITCH:
946 genPackedSwitch(cUnit, mir, rlSrc[0]);
947 break;
948
949 case Instruction::SPARSE_SWITCH:
950 genSparseSwitch(cUnit, mir, rlSrc[0], labelList);
951 break;
952
953 case Instruction::CMPL_FLOAT:
954 case Instruction::CMPG_FLOAT:
955 case Instruction::CMPL_DOUBLE:
956 case Instruction::CMPG_DOUBLE:
957 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
958 break;
959
960 case Instruction::CMP_LONG:
961 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
962 break;
963
964 case Instruction::AGET_WIDE:
965 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
966 break;
967 case Instruction::AGET:
968 case Instruction::AGET_OBJECT:
969 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
970 break;
971 case Instruction::AGET_BOOLEAN:
972 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
973 break;
974 case Instruction::AGET_BYTE:
975 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
976 break;
977 case Instruction::AGET_CHAR:
978 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
979 break;
980 case Instruction::AGET_SHORT:
981 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
982 break;
983 case Instruction::APUT_WIDE:
984 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
985 break;
986 case Instruction::APUT:
987 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
988 break;
989 case Instruction::APUT_OBJECT:
990 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
991 break;
992 case Instruction::APUT_SHORT:
993 case Instruction::APUT_CHAR:
994 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
995 break;
996 case Instruction::APUT_BYTE:
997 case Instruction::APUT_BOOLEAN:
998 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
999 rlSrc[0], 0);
1000 break;
1001
1002 case Instruction::IGET_OBJECT:
1003 //case Instruction::IGET_OBJECT_VOLATILE:
1004 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
1005 break;
1006
1007 case Instruction::IGET_WIDE:
1008 //case Instruction::IGET_WIDE_VOLATILE:
1009 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
1010 break;
1011
1012 case Instruction::IGET:
1013 //case Instruction::IGET_VOLATILE:
1014 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
1015 break;
1016
1017 case Instruction::IGET_CHAR:
1018 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
1019 break;
1020
1021 case Instruction::IGET_SHORT:
1022 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
1023 break;
1024
1025 case Instruction::IGET_BOOLEAN:
1026 case Instruction::IGET_BYTE:
1027 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
1028 break;
1029
1030 case Instruction::IPUT_WIDE:
1031 //case Instruction::IPUT_WIDE_VOLATILE:
1032 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
1033 break;
1034
1035 case Instruction::IPUT_OBJECT:
1036 //case Instruction::IPUT_OBJECT_VOLATILE:
1037 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
1038 break;
1039
1040 case Instruction::IPUT:
1041 //case Instruction::IPUT_VOLATILE:
1042 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
1043 break;
1044
1045 case Instruction::IPUT_BOOLEAN:
1046 case Instruction::IPUT_BYTE:
1047 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
1048 break;
1049
1050 case Instruction::IPUT_CHAR:
1051 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
1052 break;
1053
1054 case Instruction::IPUT_SHORT:
1055 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
1056 break;
1057
1058 case Instruction::SGET_OBJECT:
1059 genSget(cUnit, mir, rlDest, false, true);
1060 break;
1061 case Instruction::SGET:
1062 case Instruction::SGET_BOOLEAN:
1063 case Instruction::SGET_BYTE:
1064 case Instruction::SGET_CHAR:
1065 case Instruction::SGET_SHORT:
1066 genSget(cUnit, mir, rlDest, false, false);
1067 break;
1068
1069 case Instruction::SGET_WIDE:
1070 genSget(cUnit, mir, rlDest, true, false);
1071 break;
1072
1073 case Instruction::SPUT_OBJECT:
1074 genSput(cUnit, mir, rlSrc[0], false, true);
1075 break;
1076
1077 case Instruction::SPUT:
1078 case Instruction::SPUT_BOOLEAN:
1079 case Instruction::SPUT_BYTE:
1080 case Instruction::SPUT_CHAR:
1081 case Instruction::SPUT_SHORT:
1082 genSput(cUnit, mir, rlSrc[0], false, false);
1083 break;
1084
1085 case Instruction::SPUT_WIDE:
1086 genSput(cUnit, mir, rlSrc[0], true, false);
1087 break;
1088
buzbee2cfc6392012-05-07 14:51:40 -07001089 case Instruction::NEG_INT:
1090 case Instruction::NOT_INT:
1091 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1092 break;
1093
1094 case Instruction::NEG_LONG:
1095 case Instruction::NOT_LONG:
1096 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1097 break;
1098
1099 case Instruction::NEG_FLOAT:
1100 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1101 break;
1102
1103 case Instruction::NEG_DOUBLE:
1104 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1105 break;
1106
1107 case Instruction::INT_TO_LONG:
1108 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
1109 break;
1110
1111 case Instruction::LONG_TO_INT:
1112 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
1113 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
1114 storeValue(cUnit, rlDest, rlSrc[0]);
1115 break;
1116
1117 case Instruction::INT_TO_BYTE:
1118 case Instruction::INT_TO_SHORT:
1119 case Instruction::INT_TO_CHAR:
1120 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
1121 break;
1122
1123 case Instruction::INT_TO_FLOAT:
1124 case Instruction::INT_TO_DOUBLE:
1125 case Instruction::LONG_TO_FLOAT:
1126 case Instruction::LONG_TO_DOUBLE:
1127 case Instruction::FLOAT_TO_INT:
1128 case Instruction::FLOAT_TO_LONG:
1129 case Instruction::FLOAT_TO_DOUBLE:
1130 case Instruction::DOUBLE_TO_INT:
1131 case Instruction::DOUBLE_TO_LONG:
1132 case Instruction::DOUBLE_TO_FLOAT:
1133 genConversion(cUnit, mir);
1134 break;
1135
1136#endif
1137
1138 default:
1139 res = true;
1140 }
buzbeeb03f4872012-06-11 15:22:11 -07001141 if (objectDefinition) {
1142 setShadowFrameEntry(cUnit, (llvm::Value*)
1143 cUnit->llvmValues.elemList[rlDest.origSReg]);
1144 }
buzbee2cfc6392012-05-07 14:51:40 -07001145 return res;
1146}
1147
1148/* Extended MIR instructions like PHI */
1149void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1150 llvm::BasicBlock* llvmBB)
1151{
1152
1153 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1154 case kMirOpPhi: {
1155 int* incoming = (int*)mir->dalvikInsn.vB;
1156 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1157 llvm::Type* phiType =
1158 llvmTypeFromLocRec(cUnit, rlDest);
1159 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1160 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1161 RegLocation loc;
1162 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001163 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001164 i++;
1165 } else {
1166 loc = oatGetSrc(cUnit, mir, i);
1167 }
1168 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1169 getLLVMBlock(cUnit, incoming[i]));
1170 }
1171 defineValue(cUnit, phi, rlDest.origSReg);
1172 break;
1173 }
1174 case kMirOpCopy: {
1175 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1176 break;
1177 }
1178#if defined(TARGET_ARM)
1179 case kMirOpFusedCmplFloat:
1180 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1181 break;
1182 case kMirOpFusedCmpgFloat:
1183 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1184 break;
1185 case kMirOpFusedCmplDouble:
1186 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1187 break;
1188 case kMirOpFusedCmpgDouble:
1189 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1190 break;
1191 case kMirOpFusedCmpLong:
1192 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1193 break;
1194#endif
1195 default:
1196 break;
1197 }
1198}
1199
1200void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1201{
1202 cUnit->currentDalvikOffset = offset;
1203 llvm::SmallVector<llvm::Value*, 1>arrayRef;
1204 arrayRef.push_back(cUnit->irb->getInt32(offset));
1205 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1206 cUnit->irb->SetDexOffset(node);
1207}
1208
1209// Attach method info as metadata to special intrinsic
1210void setMethodInfo(CompilationUnit* cUnit)
1211{
1212 // We don't want dex offset on this
1213 cUnit->irb->SetDexOffset(NULL);
1214 greenland::IntrinsicHelper::IntrinsicId id;
1215 id = greenland::IntrinsicHelper::MethodInfo;
1216 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1217 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1218 llvm::SmallVector<llvm::Value*, 2> regInfo;
1219 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1220 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1221 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1222 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1223 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1224 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1225 inst->setMetadata("RegInfo", regInfoNode);
1226 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1227 llvm::SmallVector<llvm::Value*, 50> pmap;
1228 for (int i = 0; i < promoSize; i++) {
1229 PromotionMap* p = &cUnit->promotionMap[i];
1230 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1231 ((p->fpReg & 0xff) << 16) |
1232 ((p->coreReg & 0xff) << 8) |
1233 ((p->fpLocation & 0xf) << 4) |
1234 (p->coreLocation & 0xf);
1235 pmap.push_back(cUnit->irb->getInt32(mapData));
1236 }
1237 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1238 inst->setMetadata("PromotionMap", mapNode);
1239 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1240}
1241
1242/* Handle the content in each basic block */
1243bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1244{
1245 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1246 cUnit->irb->SetInsertPoint(llvmBB);
1247 setDexOffset(cUnit, bb->startOffset);
1248
1249 if (bb->blockType == kEntryBlock) {
1250 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001251 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1252 cUnit->numDalvikRegisters, true,
1253 kAllocMisc);
1254 for (int i = 0; i < cUnit->numSSARegs; i++) {
1255 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1256 }
1257 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1258 if (canBeRef[i]) {
1259 cUnit->numShadowFrameEntries++;
1260 }
1261 }
1262 if (cUnit->numShadowFrameEntries > 0) {
1263 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1264 cUnit->numShadowFrameEntries, true,
1265 kAllocMisc);
1266 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1267 if (canBeRef[i]) {
1268 cUnit->shadowMap[j++] = i;
1269 }
1270 }
1271 greenland::IntrinsicHelper::IntrinsicId id =
1272 greenland::IntrinsicHelper::AllocaShadowFrame;
1273 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1274 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1275 cUnit->irb->CreateCall(func, entries);
1276 }
buzbee2cfc6392012-05-07 14:51:40 -07001277 } else if (bb->blockType == kExitBlock) {
1278 /*
1279 * Because of the differences between how MIR/LIR and llvm handle exit
1280 * blocks, we won't explicitly covert them. On the llvm-to-lir
1281 * path, it will need to be regenereated.
1282 */
1283 return false;
buzbee6969d502012-06-15 16:40:31 -07001284 } else if (bb->blockType == kExceptionHandling) {
1285 /*
1286 * Because we're deferring null checking, delete the associated empty
1287 * exception block.
1288 * TODO: add new block type for exception blocks that we generate
1289 * greenland code for.
1290 */
1291 llvmBB->eraseFromParent();
1292 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001293 }
1294
1295 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1296
1297 setDexOffset(cUnit, mir->offset);
1298
1299 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1300 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1301
1302 /* If we're compiling for the debugger, generate an update callout */
1303 if (cUnit->genDebugger) {
1304 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1305 //genDebuggerUpdate(cUnit, mir->offset);
1306 }
1307
1308 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1309 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1310 continue;
1311 }
1312
1313 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1314 NULL /* labelList */);
1315 if (notHandled) {
1316 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1317 mir->offset, dalvikOpcode,
1318 Instruction::Name(dalvikOpcode),
1319 dalvikFormat);
1320 }
1321 }
1322
buzbee6969d502012-06-15 16:40:31 -07001323 if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001324 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1325 }
1326
1327 return false;
1328}
1329
1330llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1331
1332 // Get return type
1333 llvm::Type* ret_type = cUnit->irb->GetJType(cUnit->shorty[0],
1334 greenland::kAccurate);
1335
1336 // Get argument type
1337 std::vector<llvm::Type*> args_type;
1338
1339 // method object
1340 args_type.push_back(cUnit->irb->GetJMethodTy());
1341
1342 // Do we have a "this"?
1343 if ((cUnit->access_flags & kAccStatic) == 0) {
1344 args_type.push_back(cUnit->irb->GetJObjectTy());
1345 }
1346
1347 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
1348 args_type.push_back(cUnit->irb->GetJType(cUnit->shorty[i],
1349 greenland::kAccurate));
1350 }
1351
1352 return llvm::FunctionType::get(ret_type, args_type, false);
1353}
1354
1355bool createFunction(CompilationUnit* cUnit) {
1356 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1357 /* with_signature */ false));
1358 llvm::FunctionType* func_type = getFunctionType(cUnit);
1359
1360 if (func_type == NULL) {
1361 return false;
1362 }
1363
1364 cUnit->func = llvm::Function::Create(func_type,
1365 llvm::Function::ExternalLinkage,
1366 func_name, cUnit->module);
1367
1368 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1369 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1370
1371 arg_iter->setName("method");
1372 ++arg_iter;
1373
1374 int startSReg = cUnit->numRegs;
1375
1376 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1377 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1378 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1379 }
1380
1381 return true;
1382}
1383
1384bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1385{
1386 // Skip the exit block
1387 if (bb->blockType == kExitBlock) {
1388 cUnit->idToBlockMap.Put(bb->id, NULL);
1389 } else {
1390 int offset = bb->startOffset;
1391 bool entryBlock = (bb->blockType == kEntryBlock);
1392 llvm::BasicBlock* llvmBB =
1393 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001394 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001395 cUnit->func);
1396 if (entryBlock) {
1397 cUnit->entryBB = llvmBB;
1398 cUnit->placeholderBB =
1399 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1400 cUnit->func);
1401 }
1402 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1403 }
1404 return false;
1405}
1406
1407
1408/*
1409 * Convert MIR to LLVM_IR
1410 * o For each ssa name, create LLVM named value. Type these
1411 * appropriately, and ignore high half of wide and double operands.
1412 * o For each MIR basic block, create an LLVM basic block.
1413 * o Iterate through the MIR a basic block at a time, setting arguments
1414 * to recovered ssa name.
1415 */
1416void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1417{
1418 initIR(cUnit);
1419 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1420
1421 // Create the function
1422 createFunction(cUnit);
1423
1424 // Create an LLVM basic block for each MIR block in dfs preorder
1425 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1426 kPreOrderDFSTraversal, false /* isIterative */);
1427 /*
1428 * Create an llvm named value for each MIR SSA name. Note: we'll use
1429 * placeholders for all non-argument values (because we haven't seen
1430 * the definition yet).
1431 */
1432 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1433 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1434 arg_iter++; /* Skip path method */
1435 for (int i = 0; i < cUnit->numSSARegs; i++) {
1436 llvm::Value* val;
1437 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1438 if (i < cUnit->numRegs) {
1439 // Skip non-argument _0 names - should never be a use
1440 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1441 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1442 // Handle SSA defs, skipping Method* and compiler temps
1443 if (SRegToVReg(cUnit, i) < 0) {
1444 val = NULL;
1445 } else {
1446 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1447 val->setName(llvmSSAName(cUnit, i));
1448 }
1449 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1450 if (cUnit->regLocation[i].wide) {
1451 // Skip high half of wide values
1452 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1453 i++;
1454 }
1455 } else {
1456 // Recover previously-created argument values
1457 llvm::Value* argVal = arg_iter++;
1458 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
1459 }
1460 }
1461 cUnit->irb->CreateBr(cUnit->placeholderBB);
1462
1463 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1464 kPreOrderDFSTraversal, false /* Iterative */);
1465
1466 cUnit->placeholderBB->eraseFromParent();
1467
1468 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1469
buzbeead8f15e2012-06-18 14:49:45 -07001470 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1471 // Write bitcode to file
1472 std::string errmsg;
1473 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1474 oatReplaceSpecialChars(fname);
1475 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001476 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001477
buzbeead8f15e2012-06-18 14:49:45 -07001478 llvm::OwningPtr<llvm::tool_output_file> out_file(
1479 new llvm::tool_output_file(fname.c_str(), errmsg,
1480 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001481
buzbeead8f15e2012-06-18 14:49:45 -07001482 if (!errmsg.empty()) {
1483 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1484 }
1485
1486 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1487 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07001488 }
buzbee2cfc6392012-05-07 14:51:40 -07001489}
1490
1491RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1492 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001493 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001494 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1495 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07001496 std::string valName = val->getName().str();
Elliott Hughes74847412012-06-20 18:10:21 -07001497 DCHECK(!valName.empty());
buzbee2cfc6392012-05-07 14:51:40 -07001498 if (valName[0] == 'v') {
1499 int baseSReg = INVALID_SREG;
Elliott Hughes74847412012-06-20 18:10:21 -07001500 sscanf(valName.c_str(), "v%d_", &baseSReg);
buzbee2cfc6392012-05-07 14:51:40 -07001501 res = cUnit->regLocation[baseSReg];
1502 cUnit->locMap.Put(val, res);
1503 } else {
buzbee4f1181f2012-06-22 13:52:12 -07001504 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
1505 memset(&res, 0, sizeof(res));
1506 res.location = kLocPhysReg;
1507 res.lowReg = oatAllocTemp(cUnit);
1508 res.home = true;
1509 res.sRegLow = INVALID_SREG;
1510 res.origSReg = INVALID_SREG;
1511 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07001512 }
1513 } else {
1514 res = it->second;
1515 }
1516 return res;
1517}
1518
1519Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1520{
1521 Instruction::Code res = Instruction::NOP;
1522 if (isWide) {
1523 switch(op) {
1524 case kOpAdd: res = Instruction::ADD_LONG; break;
1525 case kOpSub: res = Instruction::SUB_LONG; break;
1526 case kOpMul: res = Instruction::MUL_LONG; break;
1527 case kOpDiv: res = Instruction::DIV_LONG; break;
1528 case kOpRem: res = Instruction::REM_LONG; break;
1529 case kOpAnd: res = Instruction::AND_LONG; break;
1530 case kOpOr: res = Instruction::OR_LONG; break;
1531 case kOpXor: res = Instruction::XOR_LONG; break;
1532 case kOpLsl: res = Instruction::SHL_LONG; break;
1533 case kOpLsr: res = Instruction::USHR_LONG; break;
1534 case kOpAsr: res = Instruction::SHR_LONG; break;
1535 default: LOG(FATAL) << "Unexpected OpKind " << op;
1536 }
1537 } else if (isConst){
1538 switch(op) {
1539 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
1540 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
1541 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
1542 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
1543 case kOpRem: res = Instruction::REM_INT_LIT16; break;
1544 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
1545 case kOpOr: res = Instruction::OR_INT_LIT16; break;
1546 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
1547 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
1548 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
1549 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
1550 default: LOG(FATAL) << "Unexpected OpKind " << op;
1551 }
1552 } else {
1553 switch(op) {
1554 case kOpAdd: res = Instruction::ADD_INT; break;
1555 case kOpSub: res = Instruction::SUB_INT; break;
1556 case kOpMul: res = Instruction::MUL_INT; break;
1557 case kOpDiv: res = Instruction::DIV_INT; break;
1558 case kOpRem: res = Instruction::REM_INT; break;
1559 case kOpAnd: res = Instruction::AND_INT; break;
1560 case kOpOr: res = Instruction::OR_INT; break;
1561 case kOpXor: res = Instruction::XOR_INT; break;
1562 case kOpLsl: res = Instruction::SHL_INT; break;
1563 case kOpLsr: res = Instruction::USHR_INT; break;
1564 case kOpAsr: res = Instruction::SHR_INT; break;
1565 default: LOG(FATAL) << "Unexpected OpKind " << op;
1566 }
1567 }
1568 return res;
1569}
1570
buzbee4f1181f2012-06-22 13:52:12 -07001571Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
1572{
1573 Instruction::Code res = Instruction::NOP;
1574 if (isWide) {
1575 switch(op) {
1576 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
1577 case kOpSub: res = Instruction::SUB_DOUBLE; break;
1578 case kOpMul: res = Instruction::MUL_DOUBLE; break;
1579 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
1580 case kOpRem: res = Instruction::REM_DOUBLE; break;
1581 default: LOG(FATAL) << "Unexpected OpKind " << op;
1582 }
1583 } else {
1584 switch(op) {
1585 case kOpAdd: res = Instruction::ADD_FLOAT; break;
1586 case kOpSub: res = Instruction::SUB_FLOAT; break;
1587 case kOpMul: res = Instruction::MUL_FLOAT; break;
1588 case kOpDiv: res = Instruction::DIV_FLOAT; break;
1589 case kOpRem: res = Instruction::REM_FLOAT; break;
1590 default: LOG(FATAL) << "Unexpected OpKind " << op;
1591 }
1592 }
1593 return res;
1594}
1595
1596void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1597{
1598 RegLocation rlDest = getLoc(cUnit, inst);
1599 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1600 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
1601 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
1602 if (rlDest.wide) {
1603 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1604 } else {
1605 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1606 }
1607}
1608
buzbee2cfc6392012-05-07 14:51:40 -07001609void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1610{
1611 RegLocation rlDest = getLoc(cUnit, inst);
1612 llvm::Value* lhs = inst->getOperand(0);
buzbee4f1181f2012-06-22 13:52:12 -07001613 // Special-case RSUB
1614 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
1615 if ((op == kOpSub) && (lhsImm != NULL)) {
1616 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
1617 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
1618 lhsImm->getSExtValue());
1619 return;
1620 }
1621 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001622 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1623 llvm::Value* rhs = inst->getOperand(1);
1624 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1625 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
1626 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
1627 } else {
1628 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
1629 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1630 if (rlDest.wide) {
1631 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1632 } else {
1633 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1634 }
1635 }
1636}
1637
1638void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
1639{
1640 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
1641 DCHECK(brInst != NULL);
1642 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
1643 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
1644 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
1645}
1646
1647void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
1648{
1649 // Nop - these have already been processed
1650}
1651
1652void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
1653{
1654 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
1655 llvm::Value* retVal = retInst->getReturnValue();
1656 if (retVal != NULL) {
1657 RegLocation rlSrc = getLoc(cUnit, retVal);
1658 if (rlSrc.wide) {
1659 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
1660 } else {
1661 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
1662 }
1663 }
1664 genExitSequence(cUnit);
1665}
1666
1667ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
1668{
1669 ConditionCode res = kCondAl;
1670 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07001671 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07001672 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
1673 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
1674 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07001675 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07001676 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07001677 default: LOG(FATAL) << "Unexpected llvm condition";
1678 }
1679 return res;
1680}
1681
1682void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
1683{
1684 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
1685 UNIMPLEMENTED(FATAL);
1686}
1687
1688void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
1689 llvm::BranchInst* brInst)
1690{
1691 // Get targets
1692 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
1693 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
1694 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
1695 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
1696 // Get comparison operands
1697 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
1698 ConditionCode cond = getCond(iCmpInst->getPredicate());
1699 llvm::Value* lhs = iCmpInst->getOperand(0);
1700 // Not expecting a constant as 1st operand
1701 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
1702 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1703 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
1704 llvm::Value* rhs = inst->getOperand(1);
1705#if defined(TARGET_MIPS)
1706 // Compare and branch in one shot
1707 (void)taken;
1708 (void)cond;
1709 (void)rhs;
1710 UNIMPLEMENTED(FATAL);
1711#else
1712 //Compare, then branch
1713 // TODO: handle fused CMP_LONG/IF_xxZ case
1714 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1715 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
1716 } else {
1717 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1718 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
1719 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
1720 }
1721 opCondBranch(cUnit, cond, taken);
1722#endif
1723 // Fallthrough
1724 opUnconditionalBranch(cUnit, fallThrough);
1725}
1726
1727void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
1728 llvm::Function* callee)
1729{
1730 UNIMPLEMENTED(FATAL);
1731}
1732
buzbee2cfc6392012-05-07 14:51:40 -07001733void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
1734{
buzbee4f1181f2012-06-22 13:52:12 -07001735 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07001736 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
1737 RegLocation rlDest = getLoc(cUnit, callInst);
1738 if (rlSrc.wide) {
1739 storeValueWide(cUnit, rlDest, rlSrc);
1740 } else {
1741 storeValue(cUnit, rlDest, rlSrc);
1742 }
1743}
1744
1745// Note: Immediate arg is a ConstantInt regardless of result type
1746void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
1747{
buzbee4f1181f2012-06-22 13:52:12 -07001748 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07001749 llvm::ConstantInt* src =
1750 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1751 uint64_t immval = src->getZExtValue();
1752 RegLocation rlDest = getLoc(cUnit, callInst);
1753 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
1754 if (rlDest.wide) {
1755 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
1756 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
1757 storeValueWide(cUnit, rlDest, rlResult);
1758 } else {
1759 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
1760 storeValue(cUnit, rlDest, rlResult);
1761 }
1762}
1763
buzbee6969d502012-06-15 16:40:31 -07001764void cvtConstString(CompilationUnit* cUnit, llvm::CallInst* callInst)
1765{
buzbee4f1181f2012-06-22 13:52:12 -07001766 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee6969d502012-06-15 16:40:31 -07001767 llvm::ConstantInt* stringIdxVal =
1768 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1769 uint32_t stringIdx = stringIdxVal->getZExtValue();
1770 RegLocation rlDest = getLoc(cUnit, callInst);
1771 genConstString(cUnit, stringIdx, rlDest);
1772}
1773
buzbee4f1181f2012-06-22 13:52:12 -07001774void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
1775{
1776 DCHECK(callInst->getNumArgOperands() == 1);
1777 llvm::ConstantInt* typeIdxVal =
1778 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1779 uint32_t typeIdx = typeIdxVal->getZExtValue();
1780 RegLocation rlDest = getLoc(cUnit, callInst);
1781 genNewInstance(cUnit, typeIdx, rlDest);
1782}
1783
1784void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
1785 bool isObject)
1786{
1787 DCHECK(callInst->getNumArgOperands() == 1);
1788 llvm::ConstantInt* typeIdxVal =
1789 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1790 uint32_t typeIdx = typeIdxVal->getZExtValue();
1791 RegLocation rlDest = getLoc(cUnit, callInst);
1792 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
1793}
1794
buzbee6969d502012-06-15 16:40:31 -07001795void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
1796 greenland::JType jtype)
1797{
1798 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
1799 kAllocMisc);
1800 if (jtype == greenland::kVoid) {
1801 info->result.location = kLocInvalid;
1802 } else {
1803 info->result = getLoc(cUnit, callInst);
1804 }
1805 llvm::ConstantInt* invokeTypeVal =
1806 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1807 llvm::ConstantInt* methodIndexVal =
1808 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
1809 llvm::ConstantInt* optFlagsVal =
1810 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
1811 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
1812 info->index = methodIndexVal->getZExtValue();
1813 info->optFlags = optFlagsVal->getZExtValue();
1814 info->offset = cUnit->currentDalvikOffset;
1815
1816 // FIXME - rework such that we no longer need isRange
1817 info->isRange = false;
1818
1819 // Count the argument words, and then build argument array.
1820 info->numArgWords = 0;
1821 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
1822 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
1823 info->numArgWords += tLoc.wide ? 2 : 1;
1824 }
1825 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
1826 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
1827 // Now, fill in the location records, synthesizing high loc of wide vals
1828 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07001829 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07001830 if (cUnit->printMe) {
1831 oatDumpRegLoc(info->args[next]);
1832 }
1833 if (info->args[next].wide) {
1834 next++;
1835 // TODO: Might make sense to mark this as an invalid loc
1836 info->args[next].origSReg = info->args[next-1].origSReg+1;
1837 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
1838 }
1839 next++;
1840 }
1841 genInvoke(cUnit, info);
1842}
1843
buzbeead8f15e2012-06-18 14:49:45 -07001844/* Look up the RegLocation associated with a Value. Must already be defined */
1845RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
1846{
1847 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1848 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
1849 return it->second;
1850}
1851
buzbee2cfc6392012-05-07 14:51:40 -07001852bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
1853{
1854 bool isEntry = (bb == &cUnit->func->getEntryBlock());
1855 // Define the starting label
1856 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
1857 // Extract the starting offset from the block's name
1858 if (!isEntry) {
1859 const char* blockName = bb->getName().str().c_str();
1860 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07001861 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07001862 }
1863 // Set the label kind
1864 blockLabel->opcode = kPseudoNormalBlockLabel;
1865 // Insert the label
1866 oatAppendLIR(cUnit, blockLabel);
1867
1868 // Free temp registers and reset redundant store tracking */
1869 oatResetRegPool(cUnit);
1870 oatResetDefTracking(cUnit);
1871
1872 //TODO: restore oat incoming liveness optimization
1873 oatClobberAllRegs(cUnit);
1874
buzbee6969d502012-06-15 16:40:31 -07001875 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07001876
1877 if (isEntry) {
1878 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07001879 RegLocation* argLocs = (RegLocation*)
1880 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
1881 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
1882 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
1883 for (unsigned i = 0; it != it_end; ++it) {
1884 llvm::Value* val = it;
1885 argLocs[i++] = valToLoc(cUnit, val);
1886 llvm::Type* ty = val->getType();
1887 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
1888 argLocs[i++].sRegLow = INVALID_SREG;
1889 }
1890 }
1891 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07001892 }
1893
1894 // Visit all of the instructions in the block
1895 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
1896 llvm::Instruction* inst = it;
1897 llvm::BasicBlock::iterator nextIt = ++it;
1898 // Extract the Dalvik offset from the instruction
1899 uint32_t opcode = inst->getOpcode();
1900 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
1901 if (dexOffsetNode != NULL) {
1902 llvm::ConstantInt* dexOffsetValue =
1903 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
1904 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
1905 }
1906
buzbee6969d502012-06-15 16:40:31 -07001907 oatResetRegPool(cUnit);
1908 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
1909 oatClobberAllRegs(cUnit);
1910 }
1911
1912 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
1913 oatResetDefTracking(cUnit);
1914 }
1915
1916#ifndef NDEBUG
1917 /* Reset temp tracking sanity check */
1918 cUnit->liveSReg = INVALID_SREG;
1919#endif
1920
1921 LIR* boundaryLIR;
1922 const char* instStr = "boundary";
1923 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
1924 (intptr_t) instStr);
1925 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
1926
1927 /* Remember the first LIR for thisl block*/
1928 if (headLIR == NULL) {
1929 headLIR = boundaryLIR;
1930 headLIR->defMask = ENCODE_ALL;
1931 }
1932
buzbee2cfc6392012-05-07 14:51:40 -07001933 switch(opcode) {
1934
1935 case llvm::Instruction::ICmp: {
1936 llvm::Instruction* nextInst = nextIt;
1937 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
1938 if (brInst != NULL /* and... */) {
1939 cvtICmpBr(cUnit, inst, brInst);
1940 ++it;
1941 } else {
1942 cvtICmp(cUnit, inst);
1943 }
1944 }
1945 break;
1946
1947 case llvm::Instruction::Call: {
1948 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
1949 llvm::Function* callee = callInst->getCalledFunction();
1950 greenland::IntrinsicHelper::IntrinsicId id =
1951 cUnit->intrinsic_helper->GetIntrinsicId(callee);
1952 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07001953 case greenland::IntrinsicHelper::AllocaShadowFrame:
1954 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07001955 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07001956 // Ignore shadow frame stuff for quick compiler
1957 break;
buzbee2cfc6392012-05-07 14:51:40 -07001958 case greenland::IntrinsicHelper::CopyInt:
1959 case greenland::IntrinsicHelper::CopyObj:
1960 case greenland::IntrinsicHelper::CopyFloat:
1961 case greenland::IntrinsicHelper::CopyLong:
1962 case greenland::IntrinsicHelper::CopyDouble:
1963 cvtCopy(cUnit, callInst);
1964 break;
1965 case greenland::IntrinsicHelper::ConstInt:
1966 case greenland::IntrinsicHelper::ConstObj:
1967 case greenland::IntrinsicHelper::ConstLong:
1968 case greenland::IntrinsicHelper::ConstFloat:
1969 case greenland::IntrinsicHelper::ConstDouble:
1970 cvtConst(cUnit, callInst);
1971 break;
buzbee4f1181f2012-06-22 13:52:12 -07001972 case greenland::IntrinsicHelper::DivInt:
1973 case greenland::IntrinsicHelper::DivLong:
1974 cvtBinOp(cUnit, kOpDiv, inst);
1975 break;
1976 case greenland::IntrinsicHelper::RemInt:
1977 case greenland::IntrinsicHelper::RemLong:
1978 cvtBinOp(cUnit, kOpRem, inst);
1979 break;
buzbee2cfc6392012-05-07 14:51:40 -07001980 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07001981 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07001982 break;
1983 case greenland::IntrinsicHelper::CheckSuspend:
1984 genSuspendTest(cUnit, 0 /* optFlags already applied */);
1985 break;
buzbee6969d502012-06-15 16:40:31 -07001986 case greenland::IntrinsicHelper::HLInvokeInt:
1987 cvtInvoke(cUnit, callInst, greenland::kInt);
1988 break;
buzbee4f1181f2012-06-22 13:52:12 -07001989 case greenland::IntrinsicHelper::HLInvokeObj:
1990 cvtInvoke(cUnit, callInst, greenland::kObject);
1991 break;
buzbee6969d502012-06-15 16:40:31 -07001992 case greenland::IntrinsicHelper::HLInvokeVoid:
1993 cvtInvoke(cUnit, callInst, greenland::kVoid);
1994 break;
1995 case greenland::IntrinsicHelper::ConstString:
1996 cvtConstString(cUnit, callInst);
1997 break;
buzbee4f1181f2012-06-22 13:52:12 -07001998 case greenland::IntrinsicHelper::NewInstance:
1999 cvtNewInstance(cUnit, callInst);
2000 break;
2001 case greenland::IntrinsicHelper::SgetObj:
2002 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2003 break;
buzbee2cfc6392012-05-07 14:51:40 -07002004 case greenland::IntrinsicHelper::UnknownId:
2005 cvtCall(cUnit, callInst, callee);
2006 break;
2007 default:
2008 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
2009 << cUnit->intrinsic_helper->GetName(id);
2010 }
2011 }
2012 break;
2013
2014 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
2015 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
2016 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
2017 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
2018 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
2019 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
2020 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
2021 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
2022 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
2023 case llvm::Instruction::Shl: cvtBinOp(cUnit, kOpLsl, inst); break;
2024 case llvm::Instruction::LShr: cvtBinOp(cUnit, kOpLsr, inst); break;
2025 case llvm::Instruction::AShr: cvtBinOp(cUnit, kOpAsr, inst); break;
2026 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
2027 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07002028 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
2029 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
2030 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
2031 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
2032 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07002033
2034 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07002035 case llvm::Instruction::Trunc:
2036 case llvm::Instruction::ZExt:
2037 case llvm::Instruction::SExt:
2038 case llvm::Instruction::FPToUI:
2039 case llvm::Instruction::FPToSI:
2040 case llvm::Instruction::UIToFP:
2041 case llvm::Instruction::SIToFP:
2042 case llvm::Instruction::FPTrunc:
2043 case llvm::Instruction::FPExt:
2044 case llvm::Instruction::PtrToInt:
2045 case llvm::Instruction::IntToPtr:
2046 case llvm::Instruction::Switch:
2047 case llvm::Instruction::FCmp:
2048 UNIMPLEMENTED(FATAL) << "Unimplemented llvm opcode: " << opcode; break;
buzbee4f1181f2012-06-22 13:52:12 -07002049 break;
buzbee2cfc6392012-05-07 14:51:40 -07002050
2051 case llvm::Instruction::URem:
2052 case llvm::Instruction::UDiv:
2053 case llvm::Instruction::Resume:
2054 case llvm::Instruction::Unreachable:
2055 case llvm::Instruction::Alloca:
2056 case llvm::Instruction::GetElementPtr:
2057 case llvm::Instruction::Fence:
2058 case llvm::Instruction::AtomicCmpXchg:
2059 case llvm::Instruction::AtomicRMW:
2060 case llvm::Instruction::BitCast:
2061 case llvm::Instruction::VAArg:
2062 case llvm::Instruction::Select:
2063 case llvm::Instruction::UserOp1:
2064 case llvm::Instruction::UserOp2:
2065 case llvm::Instruction::ExtractElement:
2066 case llvm::Instruction::InsertElement:
2067 case llvm::Instruction::ShuffleVector:
2068 case llvm::Instruction::ExtractValue:
2069 case llvm::Instruction::InsertValue:
2070 case llvm::Instruction::LandingPad:
2071 case llvm::Instruction::IndirectBr:
2072 case llvm::Instruction::Load:
2073 case llvm::Instruction::Store:
2074 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
2075
2076 default:
2077 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
2078 }
2079 }
buzbee6969d502012-06-15 16:40:31 -07002080
2081 if (headLIR != NULL) {
2082 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
2083 }
buzbee2cfc6392012-05-07 14:51:40 -07002084 return false;
2085}
2086
2087/*
2088 * Convert LLVM_IR to MIR:
2089 * o Iterate through the LLVM_IR and construct a graph using
2090 * standard MIR building blocks.
2091 * o Perform a basic-block optimization pass to remove unnecessary
2092 * store/load sequences.
2093 * o Convert the LLVM Value operands into RegLocations where applicable.
2094 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
2095 * o Perform register promotion
2096 * o Iterate through the graph a basic block at a time, generating
2097 * LIR.
2098 * o Assemble LIR as usual.
2099 * o Profit.
2100 */
2101void oatMethodBitcode2LIR(CompilationUnit* cUnit)
2102{
buzbeead8f15e2012-06-18 14:49:45 -07002103 llvm::Function* func = cUnit->func;
2104 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07002105 // Allocate a list for LIR basic block labels
2106 cUnit->blockLabelList =
2107 (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
2108 LIR* labelList = (LIR*)cUnit->blockLabelList;
2109 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002110 for (llvm::Function::iterator i = func->begin(),
2111 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07002112 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
2113 &labelList[nextLabel++]);
2114 }
buzbeead8f15e2012-06-18 14:49:45 -07002115
2116 /*
2117 * Keep honest - clear regLocations, Value => RegLocation,
2118 * promotion map and VmapTables.
2119 */
2120 cUnit->locMap.clear(); // Start fresh
2121 cUnit->regLocation = NULL;
2122 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
2123 i++) {
2124 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
2125 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
2126 }
2127 cUnit->coreSpillMask = 0;
2128 cUnit->numCoreSpills = 0;
2129 cUnit->fpSpillMask = 0;
2130 cUnit->numFPSpills = 0;
2131 cUnit->coreVmapTable.clear();
2132 cUnit->fpVmapTable.clear();
2133 oatAdjustSpillMask(cUnit);
2134 cUnit->frameSize = oatComputeFrameSize(cUnit);
2135
2136 /*
2137 * At this point, we've lost all knowledge of register promotion.
2138 * Rebuild that info from the MethodInfo intrinsic (if it
2139 * exists - not required for correctness).
2140 */
2141 // TODO: find and recover MethodInfo.
2142
2143 // Create RegLocations for arguments
2144 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2145 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2146 for (; it != it_end; ++it) {
2147 llvm::Value* val = it;
2148 createLocFromValue(cUnit, val);
2149 }
2150 // Create RegLocations for all non-argument defintions
2151 for (llvm::inst_iterator i = llvm::inst_begin(func),
2152 e = llvm::inst_end(func); i != e; ++i) {
2153 llvm::Value* val = &*i;
2154 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
2155 createLocFromValue(cUnit, val);
2156 }
2157 }
2158
buzbee2cfc6392012-05-07 14:51:40 -07002159 // Walk the blocks, generating code.
2160 for (llvm::Function::iterator i = cUnit->func->begin(),
2161 e = cUnit->func->end(); i != e; ++i) {
2162 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
2163 }
2164
2165 handleSuspendLaunchpads(cUnit);
2166
2167 handleThrowLaunchpads(cUnit);
2168
2169 handleIntrinsicLaunchpads(cUnit);
2170
2171 freeIR(cUnit);
2172}
2173
2174
2175} // namespace art
2176
2177#endif // ART_USE_QUICK_COMPILER