blob: 66823c2313cd383ab409fd51d22923a3ffbaa615 [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
buzbee6969d502012-06-15 16:40:31 -070032const char* labelFormat = "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)
63 res = cUnit->irb->GetJDoubleTy();
64 else
65 res = cUnit->irb->GetJLongTy();
66 } else {
67 if (loc.fp) {
68 res = cUnit->irb->GetJFloatTy();
69 } else {
70 if (loc.ref)
71 res = cUnit->irb->GetJObjectTy();
72 else
73 res = cUnit->irb->GetJIntTy();
74 }
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();
85 if (cUnit->printMe) {
86 LOG(INFO) << "Processing llvm Value " << valName;
87 }
88 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
89 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
90 int baseSReg = INVALID_SREG;
91 int subscript = -1;
92 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
93 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
94 baseSReg = SSA_METHOD_BASEREG;
95 subscript = 0;
96 }
97 if (cUnit->printMe) {
98 LOG(INFO) << "Base: " << baseSReg << ", Sub: " << subscript;
99 }
100 DCHECK_NE(baseSReg, INVALID_SREG);
101 DCHECK_NE(subscript, -1);
102 // TODO: redo during C++'ification
103 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
104 INVALID_REG, INVALID_SREG, INVALID_SREG};
105 llvm::Type* ty = val->getType();
106 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
107 (ty == cUnit->irb->getDoubleTy()));
108 loc.defined = true;
109 if ((ty == cUnit->irb->getFloatTy()) ||
110 (ty == cUnit->irb->getDoubleTy())) {
111 loc.fp = true;
112 } else if (ty == cUnit->irb->GetJObjectTy()) {
113 loc.ref = true;
114 } else {
115 loc.core = true;
116 }
117 loc.home = false; // Will change during promotion
118 loc.sRegLow = baseSReg;
119 loc.origSReg = cUnit->locMap.size();
120 cUnit->locMap.Put(val, loc);
121}
122
buzbee2cfc6392012-05-07 14:51:40 -0700123void initIR(CompilationUnit* cUnit)
124{
125 cUnit->context = new llvm::LLVMContext();
126 cUnit->module = new llvm::Module("art", *cUnit->context);
127 llvm::StructType::create(*cUnit->context, "JavaObject");
128 llvm::StructType::create(*cUnit->context, "Method");
129 llvm::StructType::create(*cUnit->context, "Thread");
130 cUnit->intrinsic_helper =
131 new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
132 cUnit->irb =
133 new greenland::IRBuilder(*cUnit->context, *cUnit->module,
134 *cUnit->intrinsic_helper);
135}
136
137void freeIR(CompilationUnit* cUnit)
138{
139 delete cUnit->irb;
140 delete cUnit->intrinsic_helper;
141 delete cUnit->module;
142 delete cUnit->context;
143}
144
145const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
146 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
147}
148
149llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
150 RegLocation loc)
151{
152 greenland::IntrinsicHelper::IntrinsicId id;
153 if (loc.wide) {
154 if (loc.fp) {
155 id = greenland::IntrinsicHelper::ConstDouble;
156 } else {
157 id = greenland::IntrinsicHelper::ConstLong;
158 }
159 } else {
160 if (loc.fp) {
161 id = greenland::IntrinsicHelper::ConstFloat;
162 } if (loc.ref) {
163 id = greenland::IntrinsicHelper::ConstObj;
164 } else {
165 id = greenland::IntrinsicHelper::ConstInt;
166 }
167 }
168 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
169 return cUnit->irb->CreateCall(intr, src);
170}
buzbeeb03f4872012-06-11 15:22:11 -0700171
172void emitPopShadowFrame(CompilationUnit* cUnit)
173{
174 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
175 greenland::IntrinsicHelper::PopShadowFrame);
176 cUnit->irb->CreateCall(intr);
177}
178
179
180
buzbee2cfc6392012-05-07 14:51:40 -0700181llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
182 RegLocation loc)
183{
184 greenland::IntrinsicHelper::IntrinsicId id;
185 if (loc.wide) {
186 if (loc.fp) {
187 id = greenland::IntrinsicHelper::CopyDouble;
188 } else {
189 id = greenland::IntrinsicHelper::CopyLong;
190 }
191 } else {
192 if (loc.fp) {
193 id = greenland::IntrinsicHelper::CopyFloat;
194 } if (loc.ref) {
195 id = greenland::IntrinsicHelper::CopyObj;
196 } else {
197 id = greenland::IntrinsicHelper::CopyInt;
198 }
199 }
200 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
201 return cUnit->irb->CreateCall(intr, src);
202}
203
204void emitSuspendCheck(CompilationUnit* cUnit)
205{
206 greenland::IntrinsicHelper::IntrinsicId id =
207 greenland::IntrinsicHelper::CheckSuspend;
208 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
209 cUnit->irb->CreateCall(intr);
210}
211
212llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
213 llvm::Value* src1, llvm::Value* src2)
214{
215 llvm::Value* res = NULL;
216 switch(cc) {
217 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
218 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
219 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
220 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
221 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
222 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
223 default: LOG(FATAL) << "Unexpected cc value " << cc;
224 }
225 return res;
226}
227
228void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
229 ConditionCode cc, RegLocation rlSrc1,
230 RegLocation rlSrc2)
231{
232 if (bb->taken->startOffset <= mir->offset) {
233 emitSuspendCheck(cUnit);
234 }
235 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
236 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
237 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
238 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
239 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
240 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700241 // Don't redo the fallthrough branch in the BB driver
242 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700243}
244
245void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
246 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
247{
248 if (bb->taken->startOffset <= mir->offset) {
249 emitSuspendCheck(cUnit);
250 }
251 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
252 llvm::Value* src2;
253 if (rlSrc1.ref) {
254 src2 = cUnit->irb->GetJNull();
255 } else {
256 src2 = cUnit->irb->getInt32(0);
257 }
258 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
259 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
260 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
261 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700262 // Don't redo the fallthrough branch in the BB driver
263 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700264}
265
266llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
267 llvm::Value* src1, llvm::Value* src2)
268{
269 greenland::IntrinsicHelper::IntrinsicId id;
270 if (isLong) {
271 if (isDiv) {
272 id = greenland::IntrinsicHelper::DivLong;
273 } else {
274 id = greenland::IntrinsicHelper::RemLong;
275 }
276 } else if (isDiv) {
277 id = greenland::IntrinsicHelper::DivInt;
278 } else {
279 id = greenland::IntrinsicHelper::RemInt;
280 }
281 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
282 llvm::SmallVector<llvm::Value*, 2>args;
283 args.push_back(src1);
284 args.push_back(src2);
285 return cUnit->irb->CreateCall(intr, args);
286}
287
288llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
289 llvm::Value* src1, llvm::Value* src2)
290{
291 llvm::Value* res = NULL;
292 switch(op) {
293 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
294 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
295 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
296 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
297 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
298 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
299 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
300 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
301 case kOpLsl: UNIMPLEMENTED(FATAL) << "Need Lsl"; break;
302 case kOpLsr: UNIMPLEMENTED(FATAL) << "Need Lsr"; break;
303 case kOpAsr: UNIMPLEMENTED(FATAL) << "Need Asr"; break;
304 default:
305 LOG(FATAL) << "Invalid op " << op;
306 }
307 return res;
308}
309
310void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
311 RegLocation rlSrc1, RegLocation rlSrc2)
312{
313 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
314 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
315 llvm::Value* res = NULL;
316 switch(op) {
317 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
318 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
319 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
320 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
321 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
322 default:
323 LOG(FATAL) << "Invalid op " << op;
324 }
325 defineValue(cUnit, res, rlDest.origSReg);
326}
327
328void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
329 RegLocation rlSrc1, RegLocation rlSrc2)
330{
331 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
332 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
333 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
334 defineValue(cUnit, res, rlDest.origSReg);
335}
336
buzbeeb03f4872012-06-11 15:22:11 -0700337void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
338{
339 int index = -1;
340 DCHECK(newVal != NULL);
341 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
342 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
343 if (cUnit->shadowMap[i] == vReg) {
344 index = i;
345 break;
346 }
347 }
348 DCHECK(index != -1) << "Corrupt shadowMap";
349 greenland::IntrinsicHelper::IntrinsicId id =
350 greenland::IntrinsicHelper::SetShadowFrameEntry;
351 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
352 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
353 llvm::Value* args[] = { newVal, tableSlot };
354 cUnit->irb->CreateCall(func, args);
355}
356
buzbee2cfc6392012-05-07 14:51:40 -0700357void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
358 RegLocation rlSrc1, int32_t imm)
359{
360 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
361 llvm::Value* src2 = cUnit->irb->getInt32(imm);
362 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
363 defineValue(cUnit, res, rlDest.origSReg);
364}
365
buzbee6969d502012-06-15 16:40:31 -0700366void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
367 InvokeType invokeType, bool isRange)
368{
369 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
370 llvm::SmallVector<llvm::Value*, 10> args;
371 // Insert the invokeType
372 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
373 // Insert the method_idx
374 args.push_back(cUnit->irb->getInt32(info->index));
375 // Insert the optimization flags
376 args.push_back(cUnit->irb->getInt32(info->optFlags));
377 // Now, insert the actual arguments
378 if (cUnit->printMe) {
379 LOG(INFO) << "Building Invoke info";
380 }
381 for (int i = 0; i < info->numArgWords;) {
382 if (cUnit->printMe) {
383 oatDumpRegLoc(info->args[i]);
384 }
385 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
386 args.push_back(val);
387 i += info->args[i].wide ? 2 : 1;
388 }
389 /*
390 * Choose the invoke return type based on actual usage. Note: may
391 * be different than shorty. For example, if a function return value
392 * is not used, we'll treat this as a void invoke.
393 */
394 greenland::IntrinsicHelper::IntrinsicId id;
395 if (info->result.location == kLocInvalid) {
396 id = greenland::IntrinsicHelper::HLInvokeVoid;
397 } else {
398 if (info->result.wide) {
399 if (info->result.fp) {
400 id = greenland::IntrinsicHelper::HLInvokeDouble;
401 } else {
402 id = greenland::IntrinsicHelper::HLInvokeFloat;
403 }
404 } else if (info->result.ref) {
405 id = greenland::IntrinsicHelper::HLInvokeObj;
406 } else if (info->result.fp) {
407 id = greenland::IntrinsicHelper::HLInvokeFloat;
408 } else {
409 id = greenland::IntrinsicHelper::HLInvokeInt;
410 }
411 }
412 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
413 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
414 if (info->result.location != kLocInvalid) {
415 defineValue(cUnit, res, info->result.origSReg);
416 }
417}
418
419void convertConstString(CompilationUnit* cUnit, BasicBlock* bb,
420 uint32_t string_idx, RegLocation rlDest)
421{
422 greenland::IntrinsicHelper::IntrinsicId id;
423 id = greenland::IntrinsicHelper::ConstString;
424 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
425 llvm::Value* index = cUnit->irb->getInt32(string_idx);
426 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
427 defineValue(cUnit, res, rlDest.origSReg);
428}
429
buzbee2cfc6392012-05-07 14:51:40 -0700430/*
431 * Target-independent code generation. Use only high-level
432 * load/store utilities here, or target-dependent genXX() handlers
433 * when necessary.
434 */
435bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
436 llvm::BasicBlock* llvmBB, LIR* labelList)
437{
438 bool res = false; // Assume success
439 RegLocation rlSrc[3];
440 RegLocation rlDest = badLoc;
441 RegLocation rlResult = badLoc;
442 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700443 uint32_t vB = mir->dalvikInsn.vB;
444 uint32_t vC = mir->dalvikInsn.vC;
445
buzbeeb03f4872012-06-11 15:22:11 -0700446 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700447
448 /* Prep Src and Dest locations */
449 int nextSreg = 0;
450 int nextLoc = 0;
451 int attrs = oatDataFlowAttributes[opcode];
452 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
453 if (attrs & DF_UA) {
454 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700455 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700456 nextSreg+= 2;
457 } else {
458 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
459 nextSreg++;
460 }
461 }
462 if (attrs & DF_UB) {
463 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700464 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700465 nextSreg+= 2;
466 } else {
467 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
468 nextSreg++;
469 }
470 }
471 if (attrs & DF_UC) {
472 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700473 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700474 } else {
475 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
476 }
477 }
478 if (attrs & DF_DA) {
479 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700480 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700481 } else {
buzbee15bf9802012-06-12 17:49:27 -0700482 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700483 if (rlDest.ref) {
484 objectDefinition = true;
485 }
buzbee2cfc6392012-05-07 14:51:40 -0700486 }
487 }
488
489 switch (opcode) {
490 case Instruction::NOP:
491 break;
492
493 case Instruction::MOVE:
494 case Instruction::MOVE_OBJECT:
495 case Instruction::MOVE_16:
496 case Instruction::MOVE_OBJECT_16:
497 case Instruction::MOVE_FROM16:
498 case Instruction::MOVE_WIDE:
499 case Instruction::MOVE_WIDE_16:
500 case Instruction::MOVE_WIDE_FROM16: {
501 /*
502 * Moves/copies are meaningless in pure SSA register form,
503 * but we need to preserve them for the conversion back into
504 * MIR (at least until we stop using the Dalvik register maps).
505 * Insert a dummy intrinsic copy call, which will be recognized
506 * by the quick path and removed by the portable path.
507 */
508 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
509 llvm::Value* res = emitCopy(cUnit, src, rlDest);
510 defineValue(cUnit, res, rlDest.origSReg);
511 }
512 break;
513
514 case Instruction::CONST:
515 case Instruction::CONST_4:
516 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700517 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700518 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
519 defineValue(cUnit, res, rlDest.origSReg);
520 }
521 break;
522
523 case Instruction::CONST_WIDE_16:
524 case Instruction::CONST_WIDE_32: {
buzbee6969d502012-06-15 16:40:31 -0700525 llvm::Constant* immValue = cUnit->irb->GetJLong(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700526 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
527 defineValue(cUnit, res, rlDest.origSReg);
528 }
529 break;
530
531 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700532 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700533 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
534 defineValue(cUnit, res, rlDest.origSReg);
535 }
536 break;
537
538 case Instruction::CONST_WIDE: {
539 llvm::Constant* immValue =
540 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
541 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
542 defineValue(cUnit, res, rlDest.origSReg);
543 }
544 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700545 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700546 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
547 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
548 defineValue(cUnit, res, rlDest.origSReg);
549 }
550
551 case Instruction::RETURN_WIDE:
552 case Instruction::RETURN:
553 case Instruction::RETURN_OBJECT: {
554 if (!cUnit->attrs & METHOD_IS_LEAF) {
555 emitSuspendCheck(cUnit);
556 }
buzbeeb03f4872012-06-11 15:22:11 -0700557 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700558 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
559 bb->hasReturn = true;
560 }
561 break;
562
563 case Instruction::RETURN_VOID: {
564 if (!cUnit->attrs & METHOD_IS_LEAF) {
565 emitSuspendCheck(cUnit);
566 }
buzbeeb03f4872012-06-11 15:22:11 -0700567 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700568 cUnit->irb->CreateRetVoid();
569 bb->hasReturn = true;
570 }
571 break;
572
573 case Instruction::IF_EQ:
574 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
575 break;
576 case Instruction::IF_NE:
577 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
578 break;
579 case Instruction::IF_LT:
580 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
581 break;
582 case Instruction::IF_GE:
583 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
584 break;
585 case Instruction::IF_GT:
586 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
587 break;
588 case Instruction::IF_LE:
589 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
590 break;
591 case Instruction::IF_EQZ:
592 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
593 break;
594 case Instruction::IF_NEZ:
595 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
596 break;
597 case Instruction::IF_LTZ:
598 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
599 break;
600 case Instruction::IF_GEZ:
601 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
602 break;
603 case Instruction::IF_GTZ:
604 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
605 break;
606 case Instruction::IF_LEZ:
607 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
608 break;
609
610 case Instruction::GOTO:
611 case Instruction::GOTO_16:
612 case Instruction::GOTO_32: {
613 if (bb->taken->startOffset <= bb->startOffset) {
614 emitSuspendCheck(cUnit);
615 }
616 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
617 }
618 break;
619
620 case Instruction::ADD_LONG:
621 case Instruction::ADD_LONG_2ADDR:
622 case Instruction::ADD_INT:
623 case Instruction::ADD_INT_2ADDR:
624 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
625 break;
626 case Instruction::SUB_LONG:
627 case Instruction::SUB_LONG_2ADDR:
628 case Instruction::SUB_INT:
629 case Instruction::SUB_INT_2ADDR:
630 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
631 break;
632 case Instruction::MUL_LONG:
633 case Instruction::MUL_LONG_2ADDR:
634 case Instruction::MUL_INT:
635 case Instruction::MUL_INT_2ADDR:
636 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
637 break;
638 case Instruction::DIV_LONG:
639 case Instruction::DIV_LONG_2ADDR:
640 case Instruction::DIV_INT:
641 case Instruction::DIV_INT_2ADDR:
642 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
643 break;
644 case Instruction::REM_LONG:
645 case Instruction::REM_LONG_2ADDR:
646 case Instruction::REM_INT:
647 case Instruction::REM_INT_2ADDR:
648 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
649 break;
650 case Instruction::AND_LONG:
651 case Instruction::AND_LONG_2ADDR:
652 case Instruction::AND_INT:
653 case Instruction::AND_INT_2ADDR:
654 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
655 break;
656 case Instruction::OR_LONG:
657 case Instruction::OR_LONG_2ADDR:
658 case Instruction::OR_INT:
659 case Instruction::OR_INT_2ADDR:
660 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
661 break;
662 case Instruction::XOR_LONG:
663 case Instruction::XOR_LONG_2ADDR:
664 case Instruction::XOR_INT:
665 case Instruction::XOR_INT_2ADDR:
666 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
667 break;
668 case Instruction::SHL_LONG:
669 case Instruction::SHL_LONG_2ADDR:
670 case Instruction::SHL_INT:
671 case Instruction::SHL_INT_2ADDR:
672 convertArithOp(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
673 break;
674 case Instruction::SHR_LONG:
675 case Instruction::SHR_LONG_2ADDR:
676 case Instruction::SHR_INT:
677 case Instruction::SHR_INT_2ADDR:
678 convertArithOp(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
679 break;
680 case Instruction::USHR_LONG:
681 case Instruction::USHR_LONG_2ADDR:
682 case Instruction::USHR_INT:
683 case Instruction::USHR_INT_2ADDR:
684 convertArithOp(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
685 break;
686
687 case Instruction::ADD_INT_LIT16:
688 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700689 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700690 break;
691 case Instruction::RSUB_INT:
692 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700693 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700694 break;
695 case Instruction::MUL_INT_LIT16:
696 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700697 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700698 break;
699 case Instruction::DIV_INT_LIT16:
700 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700701 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700702 break;
703 case Instruction::REM_INT_LIT16:
704 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700705 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700706 break;
707 case Instruction::AND_INT_LIT16:
708 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700709 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700710 break;
711 case Instruction::OR_INT_LIT16:
712 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700713 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700714 break;
715 case Instruction::XOR_INT_LIT16:
716 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700717 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700718 break;
719 case Instruction::SHL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700720 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700721 break;
722 case Instruction::SHR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700723 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700724 break;
725 case Instruction::USHR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700726 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700727 break;
728
729 case Instruction::ADD_FLOAT:
730 case Instruction::ADD_FLOAT_2ADDR:
731 case Instruction::ADD_DOUBLE:
732 case Instruction::ADD_DOUBLE_2ADDR:
733 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
734 break;
735
736 case Instruction::SUB_FLOAT:
737 case Instruction::SUB_FLOAT_2ADDR:
738 case Instruction::SUB_DOUBLE:
739 case Instruction::SUB_DOUBLE_2ADDR:
740 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
741 break;
742
743 case Instruction::MUL_FLOAT:
744 case Instruction::MUL_FLOAT_2ADDR:
745 case Instruction::MUL_DOUBLE:
746 case Instruction::MUL_DOUBLE_2ADDR:
747 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
748 break;
749
750 case Instruction::DIV_FLOAT:
751 case Instruction::DIV_FLOAT_2ADDR:
752 case Instruction::DIV_DOUBLE:
753 case Instruction::DIV_DOUBLE_2ADDR:
754 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
755 break;
756
757 case Instruction::REM_FLOAT:
758 case Instruction::REM_FLOAT_2ADDR:
759 case Instruction::REM_DOUBLE:
760 case Instruction::REM_DOUBLE_2ADDR:
761 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
762 break;
763
buzbee6969d502012-06-15 16:40:31 -0700764 case Instruction::INVOKE_STATIC:
765 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/);
766 break;
767 case Instruction::INVOKE_STATIC_RANGE:
768 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/);
769 break;
770
771 case Instruction::INVOKE_DIRECT:
772 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/);
773 break;
774 case Instruction::INVOKE_DIRECT_RANGE:
775 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/);
776 break;
777
778 case Instruction::INVOKE_VIRTUAL:
779 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/);
780 break;
781 case Instruction::INVOKE_VIRTUAL_RANGE:
782 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/);
783 break;
784
785 case Instruction::INVOKE_SUPER:
786 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/);
787 break;
788 case Instruction::INVOKE_SUPER_RANGE:
789 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/);
790 break;
791
792 case Instruction::INVOKE_INTERFACE:
793 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/);
794 break;
795 case Instruction::INVOKE_INTERFACE_RANGE:
796 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/);
797 break;
798
799 case Instruction::CONST_STRING:
800 case Instruction::CONST_STRING_JUMBO:
801 convertConstString(cUnit, bb, vB, rlDest);
802 break;
803
804
buzbee2cfc6392012-05-07 14:51:40 -0700805#if 0
806
807 case Instruction::MOVE_EXCEPTION: {
808 int exOffset = Thread::ExceptionOffset().Int32Value();
809 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
810#if defined(TARGET_X86)
811 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
812 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
813#else
814 int resetReg = oatAllocTemp(cUnit);
815 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
816 loadConstant(cUnit, resetReg, 0);
817 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
818 storeValue(cUnit, rlDest, rlResult);
819 oatFreeTemp(cUnit, resetReg);
820#endif
821 break;
822 }
823
824 case Instruction::MOVE_RESULT_WIDE:
825 if (mir->optimizationFlags & MIR_INLINED)
826 break; // Nop - combined w/ previous invoke
827 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
828 break;
829
830 case Instruction::MOVE_RESULT:
831 case Instruction::MOVE_RESULT_OBJECT:
832 if (mir->optimizationFlags & MIR_INLINED)
833 break; // Nop - combined w/ previous invoke
834 storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
835 break;
836
837 case Instruction::MONITOR_ENTER:
838 genMonitorEnter(cUnit, mir, rlSrc[0]);
839 break;
840
841 case Instruction::MONITOR_EXIT:
842 genMonitorExit(cUnit, mir, rlSrc[0]);
843 break;
844
845 case Instruction::CHECK_CAST:
846 genCheckCast(cUnit, mir, rlSrc[0]);
847 break;
848
849 case Instruction::INSTANCE_OF:
850 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
851 break;
852
853 case Instruction::NEW_INSTANCE:
854 genNewInstance(cUnit, mir, rlDest);
855 break;
856
857 case Instruction::THROW:
858 genThrow(cUnit, mir, rlSrc[0]);
859 break;
860
861 case Instruction::THROW_VERIFICATION_ERROR:
862 genThrowVerificationError(cUnit, mir);
863 break;
864
865 case Instruction::ARRAY_LENGTH:
866 int lenOffset;
867 lenOffset = Array::LengthOffset().Int32Value();
868 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
869 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
870 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
871 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
872 storeValue(cUnit, rlDest, rlResult);
873 break;
874
buzbee2cfc6392012-05-07 14:51:40 -0700875 case Instruction::CONST_CLASS:
876 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
877 break;
878
879 case Instruction::FILL_ARRAY_DATA:
880 genFillArrayData(cUnit, mir, rlSrc[0]);
881 break;
882
883 case Instruction::FILLED_NEW_ARRAY:
884 genFilledNewArray(cUnit, mir, false /* not range */);
885 break;
886
887 case Instruction::FILLED_NEW_ARRAY_RANGE:
888 genFilledNewArray(cUnit, mir, true /* range */);
889 break;
890
891 case Instruction::NEW_ARRAY:
892 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
893 break;
894
895 case Instruction::PACKED_SWITCH:
896 genPackedSwitch(cUnit, mir, rlSrc[0]);
897 break;
898
899 case Instruction::SPARSE_SWITCH:
900 genSparseSwitch(cUnit, mir, rlSrc[0], labelList);
901 break;
902
903 case Instruction::CMPL_FLOAT:
904 case Instruction::CMPG_FLOAT:
905 case Instruction::CMPL_DOUBLE:
906 case Instruction::CMPG_DOUBLE:
907 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
908 break;
909
910 case Instruction::CMP_LONG:
911 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
912 break;
913
914 case Instruction::AGET_WIDE:
915 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
916 break;
917 case Instruction::AGET:
918 case Instruction::AGET_OBJECT:
919 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
920 break;
921 case Instruction::AGET_BOOLEAN:
922 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
923 break;
924 case Instruction::AGET_BYTE:
925 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
926 break;
927 case Instruction::AGET_CHAR:
928 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
929 break;
930 case Instruction::AGET_SHORT:
931 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
932 break;
933 case Instruction::APUT_WIDE:
934 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
935 break;
936 case Instruction::APUT:
937 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
938 break;
939 case Instruction::APUT_OBJECT:
940 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
941 break;
942 case Instruction::APUT_SHORT:
943 case Instruction::APUT_CHAR:
944 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
945 break;
946 case Instruction::APUT_BYTE:
947 case Instruction::APUT_BOOLEAN:
948 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
949 rlSrc[0], 0);
950 break;
951
952 case Instruction::IGET_OBJECT:
953 //case Instruction::IGET_OBJECT_VOLATILE:
954 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
955 break;
956
957 case Instruction::IGET_WIDE:
958 //case Instruction::IGET_WIDE_VOLATILE:
959 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
960 break;
961
962 case Instruction::IGET:
963 //case Instruction::IGET_VOLATILE:
964 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
965 break;
966
967 case Instruction::IGET_CHAR:
968 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
969 break;
970
971 case Instruction::IGET_SHORT:
972 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
973 break;
974
975 case Instruction::IGET_BOOLEAN:
976 case Instruction::IGET_BYTE:
977 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
978 break;
979
980 case Instruction::IPUT_WIDE:
981 //case Instruction::IPUT_WIDE_VOLATILE:
982 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
983 break;
984
985 case Instruction::IPUT_OBJECT:
986 //case Instruction::IPUT_OBJECT_VOLATILE:
987 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
988 break;
989
990 case Instruction::IPUT:
991 //case Instruction::IPUT_VOLATILE:
992 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
993 break;
994
995 case Instruction::IPUT_BOOLEAN:
996 case Instruction::IPUT_BYTE:
997 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
998 break;
999
1000 case Instruction::IPUT_CHAR:
1001 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
1002 break;
1003
1004 case Instruction::IPUT_SHORT:
1005 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
1006 break;
1007
1008 case Instruction::SGET_OBJECT:
1009 genSget(cUnit, mir, rlDest, false, true);
1010 break;
1011 case Instruction::SGET:
1012 case Instruction::SGET_BOOLEAN:
1013 case Instruction::SGET_BYTE:
1014 case Instruction::SGET_CHAR:
1015 case Instruction::SGET_SHORT:
1016 genSget(cUnit, mir, rlDest, false, false);
1017 break;
1018
1019 case Instruction::SGET_WIDE:
1020 genSget(cUnit, mir, rlDest, true, false);
1021 break;
1022
1023 case Instruction::SPUT_OBJECT:
1024 genSput(cUnit, mir, rlSrc[0], false, true);
1025 break;
1026
1027 case Instruction::SPUT:
1028 case Instruction::SPUT_BOOLEAN:
1029 case Instruction::SPUT_BYTE:
1030 case Instruction::SPUT_CHAR:
1031 case Instruction::SPUT_SHORT:
1032 genSput(cUnit, mir, rlSrc[0], false, false);
1033 break;
1034
1035 case Instruction::SPUT_WIDE:
1036 genSput(cUnit, mir, rlSrc[0], true, false);
1037 break;
1038
buzbee2cfc6392012-05-07 14:51:40 -07001039 case Instruction::NEG_INT:
1040 case Instruction::NOT_INT:
1041 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1042 break;
1043
1044 case Instruction::NEG_LONG:
1045 case Instruction::NOT_LONG:
1046 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1047 break;
1048
1049 case Instruction::NEG_FLOAT:
1050 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1051 break;
1052
1053 case Instruction::NEG_DOUBLE:
1054 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1055 break;
1056
1057 case Instruction::INT_TO_LONG:
1058 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
1059 break;
1060
1061 case Instruction::LONG_TO_INT:
1062 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
1063 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
1064 storeValue(cUnit, rlDest, rlSrc[0]);
1065 break;
1066
1067 case Instruction::INT_TO_BYTE:
1068 case Instruction::INT_TO_SHORT:
1069 case Instruction::INT_TO_CHAR:
1070 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
1071 break;
1072
1073 case Instruction::INT_TO_FLOAT:
1074 case Instruction::INT_TO_DOUBLE:
1075 case Instruction::LONG_TO_FLOAT:
1076 case Instruction::LONG_TO_DOUBLE:
1077 case Instruction::FLOAT_TO_INT:
1078 case Instruction::FLOAT_TO_LONG:
1079 case Instruction::FLOAT_TO_DOUBLE:
1080 case Instruction::DOUBLE_TO_INT:
1081 case Instruction::DOUBLE_TO_LONG:
1082 case Instruction::DOUBLE_TO_FLOAT:
1083 genConversion(cUnit, mir);
1084 break;
1085
1086#endif
1087
1088 default:
1089 res = true;
1090 }
buzbeeb03f4872012-06-11 15:22:11 -07001091 if (objectDefinition) {
1092 setShadowFrameEntry(cUnit, (llvm::Value*)
1093 cUnit->llvmValues.elemList[rlDest.origSReg]);
1094 }
buzbee2cfc6392012-05-07 14:51:40 -07001095 return res;
1096}
1097
1098/* Extended MIR instructions like PHI */
1099void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1100 llvm::BasicBlock* llvmBB)
1101{
1102
1103 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1104 case kMirOpPhi: {
1105 int* incoming = (int*)mir->dalvikInsn.vB;
1106 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1107 llvm::Type* phiType =
1108 llvmTypeFromLocRec(cUnit, rlDest);
1109 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1110 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1111 RegLocation loc;
1112 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001113 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001114 i++;
1115 } else {
1116 loc = oatGetSrc(cUnit, mir, i);
1117 }
1118 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1119 getLLVMBlock(cUnit, incoming[i]));
1120 }
1121 defineValue(cUnit, phi, rlDest.origSReg);
1122 break;
1123 }
1124 case kMirOpCopy: {
1125 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1126 break;
1127 }
1128#if defined(TARGET_ARM)
1129 case kMirOpFusedCmplFloat:
1130 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1131 break;
1132 case kMirOpFusedCmpgFloat:
1133 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1134 break;
1135 case kMirOpFusedCmplDouble:
1136 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1137 break;
1138 case kMirOpFusedCmpgDouble:
1139 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1140 break;
1141 case kMirOpFusedCmpLong:
1142 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1143 break;
1144#endif
1145 default:
1146 break;
1147 }
1148}
1149
1150void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1151{
1152 cUnit->currentDalvikOffset = offset;
1153 llvm::SmallVector<llvm::Value*, 1>arrayRef;
1154 arrayRef.push_back(cUnit->irb->getInt32(offset));
1155 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1156 cUnit->irb->SetDexOffset(node);
1157}
1158
1159// Attach method info as metadata to special intrinsic
1160void setMethodInfo(CompilationUnit* cUnit)
1161{
1162 // We don't want dex offset on this
1163 cUnit->irb->SetDexOffset(NULL);
1164 greenland::IntrinsicHelper::IntrinsicId id;
1165 id = greenland::IntrinsicHelper::MethodInfo;
1166 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1167 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1168 llvm::SmallVector<llvm::Value*, 2> regInfo;
1169 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1170 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1171 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1172 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1173 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1174 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1175 inst->setMetadata("RegInfo", regInfoNode);
1176 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1177 llvm::SmallVector<llvm::Value*, 50> pmap;
1178 for (int i = 0; i < promoSize; i++) {
1179 PromotionMap* p = &cUnit->promotionMap[i];
1180 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1181 ((p->fpReg & 0xff) << 16) |
1182 ((p->coreReg & 0xff) << 8) |
1183 ((p->fpLocation & 0xf) << 4) |
1184 (p->coreLocation & 0xf);
1185 pmap.push_back(cUnit->irb->getInt32(mapData));
1186 }
1187 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1188 inst->setMetadata("PromotionMap", mapNode);
1189 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1190}
1191
1192/* Handle the content in each basic block */
1193bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1194{
1195 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1196 cUnit->irb->SetInsertPoint(llvmBB);
1197 setDexOffset(cUnit, bb->startOffset);
1198
1199 if (bb->blockType == kEntryBlock) {
1200 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001201 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1202 cUnit->numDalvikRegisters, true,
1203 kAllocMisc);
1204 for (int i = 0; i < cUnit->numSSARegs; i++) {
1205 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1206 }
1207 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1208 if (canBeRef[i]) {
1209 cUnit->numShadowFrameEntries++;
1210 }
1211 }
1212 if (cUnit->numShadowFrameEntries > 0) {
1213 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1214 cUnit->numShadowFrameEntries, true,
1215 kAllocMisc);
1216 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1217 if (canBeRef[i]) {
1218 cUnit->shadowMap[j++] = i;
1219 }
1220 }
1221 greenland::IntrinsicHelper::IntrinsicId id =
1222 greenland::IntrinsicHelper::AllocaShadowFrame;
1223 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1224 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1225 cUnit->irb->CreateCall(func, entries);
1226 }
buzbee2cfc6392012-05-07 14:51:40 -07001227 } else if (bb->blockType == kExitBlock) {
1228 /*
1229 * Because of the differences between how MIR/LIR and llvm handle exit
1230 * blocks, we won't explicitly covert them. On the llvm-to-lir
1231 * path, it will need to be regenereated.
1232 */
1233 return false;
buzbee6969d502012-06-15 16:40:31 -07001234 } else if (bb->blockType == kExceptionHandling) {
1235 /*
1236 * Because we're deferring null checking, delete the associated empty
1237 * exception block.
1238 * TODO: add new block type for exception blocks that we generate
1239 * greenland code for.
1240 */
1241 llvmBB->eraseFromParent();
1242 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001243 }
1244
1245 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1246
1247 setDexOffset(cUnit, mir->offset);
1248
1249 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1250 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1251
1252 /* If we're compiling for the debugger, generate an update callout */
1253 if (cUnit->genDebugger) {
1254 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1255 //genDebuggerUpdate(cUnit, mir->offset);
1256 }
1257
1258 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1259 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1260 continue;
1261 }
1262
1263 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1264 NULL /* labelList */);
1265 if (notHandled) {
1266 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1267 mir->offset, dalvikOpcode,
1268 Instruction::Name(dalvikOpcode),
1269 dalvikFormat);
1270 }
1271 }
1272
buzbee6969d502012-06-15 16:40:31 -07001273 if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001274 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1275 }
1276
1277 return false;
1278}
1279
1280llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1281
1282 // Get return type
1283 llvm::Type* ret_type = cUnit->irb->GetJType(cUnit->shorty[0],
1284 greenland::kAccurate);
1285
1286 // Get argument type
1287 std::vector<llvm::Type*> args_type;
1288
1289 // method object
1290 args_type.push_back(cUnit->irb->GetJMethodTy());
1291
1292 // Do we have a "this"?
1293 if ((cUnit->access_flags & kAccStatic) == 0) {
1294 args_type.push_back(cUnit->irb->GetJObjectTy());
1295 }
1296
1297 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
1298 args_type.push_back(cUnit->irb->GetJType(cUnit->shorty[i],
1299 greenland::kAccurate));
1300 }
1301
1302 return llvm::FunctionType::get(ret_type, args_type, false);
1303}
1304
1305bool createFunction(CompilationUnit* cUnit) {
1306 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1307 /* with_signature */ false));
1308 llvm::FunctionType* func_type = getFunctionType(cUnit);
1309
1310 if (func_type == NULL) {
1311 return false;
1312 }
1313
1314 cUnit->func = llvm::Function::Create(func_type,
1315 llvm::Function::ExternalLinkage,
1316 func_name, cUnit->module);
1317
1318 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1319 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1320
1321 arg_iter->setName("method");
1322 ++arg_iter;
1323
1324 int startSReg = cUnit->numRegs;
1325
1326 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1327 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1328 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1329 }
1330
1331 return true;
1332}
1333
1334bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1335{
1336 // Skip the exit block
1337 if (bb->blockType == kExitBlock) {
1338 cUnit->idToBlockMap.Put(bb->id, NULL);
1339 } else {
1340 int offset = bb->startOffset;
1341 bool entryBlock = (bb->blockType == kEntryBlock);
1342 llvm::BasicBlock* llvmBB =
1343 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
1344 StringPrintf(labelFormat, offset, bb->id),
1345 cUnit->func);
1346 if (entryBlock) {
1347 cUnit->entryBB = llvmBB;
1348 cUnit->placeholderBB =
1349 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1350 cUnit->func);
1351 }
1352 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1353 }
1354 return false;
1355}
1356
1357
1358/*
1359 * Convert MIR to LLVM_IR
1360 * o For each ssa name, create LLVM named value. Type these
1361 * appropriately, and ignore high half of wide and double operands.
1362 * o For each MIR basic block, create an LLVM basic block.
1363 * o Iterate through the MIR a basic block at a time, setting arguments
1364 * to recovered ssa name.
1365 */
1366void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1367{
1368 initIR(cUnit);
1369 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1370
1371 // Create the function
1372 createFunction(cUnit);
1373
1374 // Create an LLVM basic block for each MIR block in dfs preorder
1375 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1376 kPreOrderDFSTraversal, false /* isIterative */);
1377 /*
1378 * Create an llvm named value for each MIR SSA name. Note: we'll use
1379 * placeholders for all non-argument values (because we haven't seen
1380 * the definition yet).
1381 */
1382 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1383 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1384 arg_iter++; /* Skip path method */
1385 for (int i = 0; i < cUnit->numSSARegs; i++) {
1386 llvm::Value* val;
1387 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1388 if (i < cUnit->numRegs) {
1389 // Skip non-argument _0 names - should never be a use
1390 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1391 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1392 // Handle SSA defs, skipping Method* and compiler temps
1393 if (SRegToVReg(cUnit, i) < 0) {
1394 val = NULL;
1395 } else {
1396 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1397 val->setName(llvmSSAName(cUnit, i));
1398 }
1399 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1400 if (cUnit->regLocation[i].wide) {
1401 // Skip high half of wide values
1402 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1403 i++;
1404 }
1405 } else {
1406 // Recover previously-created argument values
1407 llvm::Value* argVal = arg_iter++;
1408 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
1409 }
1410 }
1411 cUnit->irb->CreateBr(cUnit->placeholderBB);
1412
1413 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1414 kPreOrderDFSTraversal, false /* Iterative */);
1415
1416 cUnit->placeholderBB->eraseFromParent();
1417
1418 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1419
buzbeead8f15e2012-06-18 14:49:45 -07001420 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1421 // Write bitcode to file
1422 std::string errmsg;
1423 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1424 oatReplaceSpecialChars(fname);
1425 // TODO: make configurable
1426 fname = StringPrintf("/tmp/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001427
buzbeead8f15e2012-06-18 14:49:45 -07001428 llvm::OwningPtr<llvm::tool_output_file> out_file(
1429 new llvm::tool_output_file(fname.c_str(), errmsg,
1430 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001431
buzbeead8f15e2012-06-18 14:49:45 -07001432 if (!errmsg.empty()) {
1433 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1434 }
1435
1436 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1437 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07001438 }
buzbee2cfc6392012-05-07 14:51:40 -07001439}
1440
1441RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1442 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001443 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001444 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1445 if (it == cUnit->locMap.end()) {
1446 const char* valName = val->getName().str().c_str();
1447 DCHECK(valName != NULL);
1448 DCHECK(strlen(valName) > 0);
1449 if (valName[0] == 'v') {
1450 int baseSReg = INVALID_SREG;
1451 sscanf(valName, "v%d_", &baseSReg);
1452 res = cUnit->regLocation[baseSReg];
1453 cUnit->locMap.Put(val, res);
1454 } else {
1455 UNIMPLEMENTED(WARNING) << "Need to handle llvm temps";
1456 DCHECK(valName[0] == 't');
1457 }
1458 } else {
1459 res = it->second;
1460 }
1461 return res;
1462}
1463
1464Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1465{
1466 Instruction::Code res = Instruction::NOP;
1467 if (isWide) {
1468 switch(op) {
1469 case kOpAdd: res = Instruction::ADD_LONG; break;
1470 case kOpSub: res = Instruction::SUB_LONG; break;
1471 case kOpMul: res = Instruction::MUL_LONG; break;
1472 case kOpDiv: res = Instruction::DIV_LONG; break;
1473 case kOpRem: res = Instruction::REM_LONG; break;
1474 case kOpAnd: res = Instruction::AND_LONG; break;
1475 case kOpOr: res = Instruction::OR_LONG; break;
1476 case kOpXor: res = Instruction::XOR_LONG; break;
1477 case kOpLsl: res = Instruction::SHL_LONG; break;
1478 case kOpLsr: res = Instruction::USHR_LONG; break;
1479 case kOpAsr: res = Instruction::SHR_LONG; break;
1480 default: LOG(FATAL) << "Unexpected OpKind " << op;
1481 }
1482 } else if (isConst){
1483 switch(op) {
1484 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
1485 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
1486 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
1487 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
1488 case kOpRem: res = Instruction::REM_INT_LIT16; break;
1489 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
1490 case kOpOr: res = Instruction::OR_INT_LIT16; break;
1491 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
1492 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
1493 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
1494 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
1495 default: LOG(FATAL) << "Unexpected OpKind " << op;
1496 }
1497 } else {
1498 switch(op) {
1499 case kOpAdd: res = Instruction::ADD_INT; break;
1500 case kOpSub: res = Instruction::SUB_INT; break;
1501 case kOpMul: res = Instruction::MUL_INT; break;
1502 case kOpDiv: res = Instruction::DIV_INT; break;
1503 case kOpRem: res = Instruction::REM_INT; break;
1504 case kOpAnd: res = Instruction::AND_INT; break;
1505 case kOpOr: res = Instruction::OR_INT; break;
1506 case kOpXor: res = Instruction::XOR_INT; break;
1507 case kOpLsl: res = Instruction::SHL_INT; break;
1508 case kOpLsr: res = Instruction::USHR_INT; break;
1509 case kOpAsr: res = Instruction::SHR_INT; break;
1510 default: LOG(FATAL) << "Unexpected OpKind " << op;
1511 }
1512 }
1513 return res;
1514}
1515
1516void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1517{
1518 RegLocation rlDest = getLoc(cUnit, inst);
1519 llvm::Value* lhs = inst->getOperand(0);
1520 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
1521 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1522 llvm::Value* rhs = inst->getOperand(1);
1523 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1524 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
1525 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
1526 } else {
1527 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
1528 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1529 if (rlDest.wide) {
1530 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1531 } else {
1532 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1533 }
1534 }
1535}
1536
1537void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
1538{
1539 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
1540 DCHECK(brInst != NULL);
1541 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
1542 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
1543 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
1544}
1545
1546void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
1547{
1548 // Nop - these have already been processed
1549}
1550
1551void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
1552{
1553 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
1554 llvm::Value* retVal = retInst->getReturnValue();
1555 if (retVal != NULL) {
1556 RegLocation rlSrc = getLoc(cUnit, retVal);
1557 if (rlSrc.wide) {
1558 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
1559 } else {
1560 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
1561 }
1562 }
1563 genExitSequence(cUnit);
1564}
1565
1566ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
1567{
1568 ConditionCode res = kCondAl;
1569 switch(llvmCond) {
1570 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
buzbee6969d502012-06-15 16:40:31 -07001571 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee2cfc6392012-05-07 14:51:40 -07001572 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
1573 default: LOG(FATAL) << "Unexpected llvm condition";
1574 }
1575 return res;
1576}
1577
1578void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
1579{
1580 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
1581 UNIMPLEMENTED(FATAL);
1582}
1583
1584void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
1585 llvm::BranchInst* brInst)
1586{
1587 // Get targets
1588 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
1589 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
1590 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
1591 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
1592 // Get comparison operands
1593 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
1594 ConditionCode cond = getCond(iCmpInst->getPredicate());
1595 llvm::Value* lhs = iCmpInst->getOperand(0);
1596 // Not expecting a constant as 1st operand
1597 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
1598 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1599 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
1600 llvm::Value* rhs = inst->getOperand(1);
1601#if defined(TARGET_MIPS)
1602 // Compare and branch in one shot
1603 (void)taken;
1604 (void)cond;
1605 (void)rhs;
1606 UNIMPLEMENTED(FATAL);
1607#else
1608 //Compare, then branch
1609 // TODO: handle fused CMP_LONG/IF_xxZ case
1610 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1611 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
1612 } else {
1613 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1614 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
1615 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
1616 }
1617 opCondBranch(cUnit, cond, taken);
1618#endif
1619 // Fallthrough
1620 opUnconditionalBranch(cUnit, fallThrough);
1621}
1622
1623void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
1624 llvm::Function* callee)
1625{
1626 UNIMPLEMENTED(FATAL);
1627}
1628
buzbee2cfc6392012-05-07 14:51:40 -07001629void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
1630{
1631 DCHECK(callInst->getNumArgOperands() == 1);
1632 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
1633 RegLocation rlDest = getLoc(cUnit, callInst);
1634 if (rlSrc.wide) {
1635 storeValueWide(cUnit, rlDest, rlSrc);
1636 } else {
1637 storeValue(cUnit, rlDest, rlSrc);
1638 }
1639}
1640
1641// Note: Immediate arg is a ConstantInt regardless of result type
1642void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
1643{
1644 DCHECK(callInst->getNumArgOperands() == 1);
1645 llvm::ConstantInt* src =
1646 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1647 uint64_t immval = src->getZExtValue();
1648 RegLocation rlDest = getLoc(cUnit, callInst);
1649 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
1650 if (rlDest.wide) {
1651 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
1652 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
1653 storeValueWide(cUnit, rlDest, rlResult);
1654 } else {
1655 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
1656 storeValue(cUnit, rlDest, rlResult);
1657 }
1658}
1659
buzbee6969d502012-06-15 16:40:31 -07001660void cvtConstString(CompilationUnit* cUnit, llvm::CallInst* callInst)
1661{
1662 DCHECK(callInst->getNumArgOperands() == 1);
1663 llvm::ConstantInt* stringIdxVal =
1664 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1665 uint32_t stringIdx = stringIdxVal->getZExtValue();
1666 RegLocation rlDest = getLoc(cUnit, callInst);
1667 genConstString(cUnit, stringIdx, rlDest);
1668}
1669
1670void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
1671 greenland::JType jtype)
1672{
1673 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
1674 kAllocMisc);
1675 if (jtype == greenland::kVoid) {
1676 info->result.location = kLocInvalid;
1677 } else {
1678 info->result = getLoc(cUnit, callInst);
1679 }
1680 llvm::ConstantInt* invokeTypeVal =
1681 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1682 llvm::ConstantInt* methodIndexVal =
1683 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
1684 llvm::ConstantInt* optFlagsVal =
1685 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
1686 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
1687 info->index = methodIndexVal->getZExtValue();
1688 info->optFlags = optFlagsVal->getZExtValue();
1689 info->offset = cUnit->currentDalvikOffset;
1690
1691 // FIXME - rework such that we no longer need isRange
1692 info->isRange = false;
1693
1694 // Count the argument words, and then build argument array.
1695 info->numArgWords = 0;
1696 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
1697 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
1698 info->numArgWords += tLoc.wide ? 2 : 1;
1699 }
1700 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
1701 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
1702 // Now, fill in the location records, synthesizing high loc of wide vals
1703 for (int i = 3, next = 0; next < info->numArgWords;) {
1704 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i));
1705 if (cUnit->printMe) {
1706 oatDumpRegLoc(info->args[next]);
1707 }
1708 if (info->args[next].wide) {
1709 next++;
1710 // TODO: Might make sense to mark this as an invalid loc
1711 info->args[next].origSReg = info->args[next-1].origSReg+1;
1712 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
1713 }
1714 next++;
1715 }
1716 genInvoke(cUnit, info);
1717}
1718
buzbeead8f15e2012-06-18 14:49:45 -07001719/* Look up the RegLocation associated with a Value. Must already be defined */
1720RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
1721{
1722 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1723 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
1724 return it->second;
1725}
1726
buzbee2cfc6392012-05-07 14:51:40 -07001727bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
1728{
1729 bool isEntry = (bb == &cUnit->func->getEntryBlock());
1730 // Define the starting label
1731 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
1732 // Extract the starting offset from the block's name
1733 if (!isEntry) {
1734 const char* blockName = bb->getName().str().c_str();
1735 int dummy;
1736 sscanf(blockName, labelFormat, &blockLabel->operands[0], &dummy);
1737 }
1738 // Set the label kind
1739 blockLabel->opcode = kPseudoNormalBlockLabel;
1740 // Insert the label
1741 oatAppendLIR(cUnit, blockLabel);
1742
1743 // Free temp registers and reset redundant store tracking */
1744 oatResetRegPool(cUnit);
1745 oatResetDefTracking(cUnit);
1746
1747 //TODO: restore oat incoming liveness optimization
1748 oatClobberAllRegs(cUnit);
1749
buzbee6969d502012-06-15 16:40:31 -07001750 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07001751
1752 if (isEntry) {
1753 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07001754 RegLocation* argLocs = (RegLocation*)
1755 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
1756 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
1757 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
1758 for (unsigned i = 0; it != it_end; ++it) {
1759 llvm::Value* val = it;
1760 argLocs[i++] = valToLoc(cUnit, val);
1761 llvm::Type* ty = val->getType();
1762 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
1763 argLocs[i++].sRegLow = INVALID_SREG;
1764 }
1765 }
1766 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07001767 }
1768
1769 // Visit all of the instructions in the block
1770 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
1771 llvm::Instruction* inst = it;
1772 llvm::BasicBlock::iterator nextIt = ++it;
1773 // Extract the Dalvik offset from the instruction
1774 uint32_t opcode = inst->getOpcode();
1775 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
1776 if (dexOffsetNode != NULL) {
1777 llvm::ConstantInt* dexOffsetValue =
1778 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
1779 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
1780 }
1781
buzbee6969d502012-06-15 16:40:31 -07001782 oatResetRegPool(cUnit);
1783 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
1784 oatClobberAllRegs(cUnit);
1785 }
1786
1787 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
1788 oatResetDefTracking(cUnit);
1789 }
1790
1791#ifndef NDEBUG
1792 /* Reset temp tracking sanity check */
1793 cUnit->liveSReg = INVALID_SREG;
1794#endif
1795
1796 LIR* boundaryLIR;
1797 const char* instStr = "boundary";
1798 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
1799 (intptr_t) instStr);
1800 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
1801
1802 /* Remember the first LIR for thisl block*/
1803 if (headLIR == NULL) {
1804 headLIR = boundaryLIR;
1805 headLIR->defMask = ENCODE_ALL;
1806 }
1807
buzbee2cfc6392012-05-07 14:51:40 -07001808 switch(opcode) {
1809
1810 case llvm::Instruction::ICmp: {
1811 llvm::Instruction* nextInst = nextIt;
1812 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
1813 if (brInst != NULL /* and... */) {
1814 cvtICmpBr(cUnit, inst, brInst);
1815 ++it;
1816 } else {
1817 cvtICmp(cUnit, inst);
1818 }
1819 }
1820 break;
1821
1822 case llvm::Instruction::Call: {
1823 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
1824 llvm::Function* callee = callInst->getCalledFunction();
1825 greenland::IntrinsicHelper::IntrinsicId id =
1826 cUnit->intrinsic_helper->GetIntrinsicId(callee);
1827 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07001828 case greenland::IntrinsicHelper::AllocaShadowFrame:
1829 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07001830 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07001831 // Ignore shadow frame stuff for quick compiler
1832 break;
buzbee2cfc6392012-05-07 14:51:40 -07001833 case greenland::IntrinsicHelper::CopyInt:
1834 case greenland::IntrinsicHelper::CopyObj:
1835 case greenland::IntrinsicHelper::CopyFloat:
1836 case greenland::IntrinsicHelper::CopyLong:
1837 case greenland::IntrinsicHelper::CopyDouble:
1838 cvtCopy(cUnit, callInst);
1839 break;
1840 case greenland::IntrinsicHelper::ConstInt:
1841 case greenland::IntrinsicHelper::ConstObj:
1842 case greenland::IntrinsicHelper::ConstLong:
1843 case greenland::IntrinsicHelper::ConstFloat:
1844 case greenland::IntrinsicHelper::ConstDouble:
1845 cvtConst(cUnit, callInst);
1846 break;
1847 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07001848 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07001849 break;
1850 case greenland::IntrinsicHelper::CheckSuspend:
1851 genSuspendTest(cUnit, 0 /* optFlags already applied */);
1852 break;
buzbee6969d502012-06-15 16:40:31 -07001853 case greenland::IntrinsicHelper::HLInvokeInt:
1854 cvtInvoke(cUnit, callInst, greenland::kInt);
1855 break;
1856 case greenland::IntrinsicHelper::HLInvokeVoid:
1857 cvtInvoke(cUnit, callInst, greenland::kVoid);
1858 break;
1859 case greenland::IntrinsicHelper::ConstString:
1860 cvtConstString(cUnit, callInst);
1861 break;
buzbee2cfc6392012-05-07 14:51:40 -07001862 case greenland::IntrinsicHelper::UnknownId:
1863 cvtCall(cUnit, callInst, callee);
1864 break;
1865 default:
1866 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
1867 << cUnit->intrinsic_helper->GetName(id);
1868 }
1869 }
1870 break;
1871
1872 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
1873 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
1874 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
1875 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
1876 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
1877 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
1878 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
1879 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
1880 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
1881 case llvm::Instruction::Shl: cvtBinOp(cUnit, kOpLsl, inst); break;
1882 case llvm::Instruction::LShr: cvtBinOp(cUnit, kOpLsr, inst); break;
1883 case llvm::Instruction::AShr: cvtBinOp(cUnit, kOpAsr, inst); break;
1884 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
1885 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
1886
1887 case llvm::Instruction::Invoke:
1888 case llvm::Instruction::FAdd:
1889 case llvm::Instruction::FSub:
1890 case llvm::Instruction::FMul:
1891 case llvm::Instruction::FDiv:
1892 case llvm::Instruction::FRem:
1893 case llvm::Instruction::Trunc:
1894 case llvm::Instruction::ZExt:
1895 case llvm::Instruction::SExt:
1896 case llvm::Instruction::FPToUI:
1897 case llvm::Instruction::FPToSI:
1898 case llvm::Instruction::UIToFP:
1899 case llvm::Instruction::SIToFP:
1900 case llvm::Instruction::FPTrunc:
1901 case llvm::Instruction::FPExt:
1902 case llvm::Instruction::PtrToInt:
1903 case llvm::Instruction::IntToPtr:
1904 case llvm::Instruction::Switch:
1905 case llvm::Instruction::FCmp:
1906 UNIMPLEMENTED(FATAL) << "Unimplemented llvm opcode: " << opcode; break;
1907
1908 case llvm::Instruction::URem:
1909 case llvm::Instruction::UDiv:
1910 case llvm::Instruction::Resume:
1911 case llvm::Instruction::Unreachable:
1912 case llvm::Instruction::Alloca:
1913 case llvm::Instruction::GetElementPtr:
1914 case llvm::Instruction::Fence:
1915 case llvm::Instruction::AtomicCmpXchg:
1916 case llvm::Instruction::AtomicRMW:
1917 case llvm::Instruction::BitCast:
1918 case llvm::Instruction::VAArg:
1919 case llvm::Instruction::Select:
1920 case llvm::Instruction::UserOp1:
1921 case llvm::Instruction::UserOp2:
1922 case llvm::Instruction::ExtractElement:
1923 case llvm::Instruction::InsertElement:
1924 case llvm::Instruction::ShuffleVector:
1925 case llvm::Instruction::ExtractValue:
1926 case llvm::Instruction::InsertValue:
1927 case llvm::Instruction::LandingPad:
1928 case llvm::Instruction::IndirectBr:
1929 case llvm::Instruction::Load:
1930 case llvm::Instruction::Store:
1931 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
1932
1933 default:
1934 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
1935 }
1936 }
buzbee6969d502012-06-15 16:40:31 -07001937
1938 if (headLIR != NULL) {
1939 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
1940 }
buzbee2cfc6392012-05-07 14:51:40 -07001941 return false;
1942}
1943
1944/*
1945 * Convert LLVM_IR to MIR:
1946 * o Iterate through the LLVM_IR and construct a graph using
1947 * standard MIR building blocks.
1948 * o Perform a basic-block optimization pass to remove unnecessary
1949 * store/load sequences.
1950 * o Convert the LLVM Value operands into RegLocations where applicable.
1951 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
1952 * o Perform register promotion
1953 * o Iterate through the graph a basic block at a time, generating
1954 * LIR.
1955 * o Assemble LIR as usual.
1956 * o Profit.
1957 */
1958void oatMethodBitcode2LIR(CompilationUnit* cUnit)
1959{
buzbeead8f15e2012-06-18 14:49:45 -07001960 llvm::Function* func = cUnit->func;
1961 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07001962 // Allocate a list for LIR basic block labels
1963 cUnit->blockLabelList =
1964 (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
1965 LIR* labelList = (LIR*)cUnit->blockLabelList;
1966 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07001967 for (llvm::Function::iterator i = func->begin(),
1968 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07001969 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
1970 &labelList[nextLabel++]);
1971 }
buzbeead8f15e2012-06-18 14:49:45 -07001972
1973 /*
1974 * Keep honest - clear regLocations, Value => RegLocation,
1975 * promotion map and VmapTables.
1976 */
1977 cUnit->locMap.clear(); // Start fresh
1978 cUnit->regLocation = NULL;
1979 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1980 i++) {
1981 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
1982 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
1983 }
1984 cUnit->coreSpillMask = 0;
1985 cUnit->numCoreSpills = 0;
1986 cUnit->fpSpillMask = 0;
1987 cUnit->numFPSpills = 0;
1988 cUnit->coreVmapTable.clear();
1989 cUnit->fpVmapTable.clear();
1990 oatAdjustSpillMask(cUnit);
1991 cUnit->frameSize = oatComputeFrameSize(cUnit);
1992
1993 /*
1994 * At this point, we've lost all knowledge of register promotion.
1995 * Rebuild that info from the MethodInfo intrinsic (if it
1996 * exists - not required for correctness).
1997 */
1998 // TODO: find and recover MethodInfo.
1999
2000 // Create RegLocations for arguments
2001 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2002 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2003 for (; it != it_end; ++it) {
2004 llvm::Value* val = it;
2005 createLocFromValue(cUnit, val);
2006 }
2007 // Create RegLocations for all non-argument defintions
2008 for (llvm::inst_iterator i = llvm::inst_begin(func),
2009 e = llvm::inst_end(func); i != e; ++i) {
2010 llvm::Value* val = &*i;
2011 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
2012 createLocFromValue(cUnit, val);
2013 }
2014 }
2015
buzbee2cfc6392012-05-07 14:51:40 -07002016 // Walk the blocks, generating code.
2017 for (llvm::Function::iterator i = cUnit->func->begin(),
2018 e = cUnit->func->end(); i != e; ++i) {
2019 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
2020 }
2021
2022 handleSuspendLaunchpads(cUnit);
2023
2024 handleThrowLaunchpads(cUnit);
2025
2026 handleIntrinsicLaunchpads(cUnit);
2027
2028 freeIR(cUnit);
2029}
2030
2031
2032} // namespace art
2033
2034#endif // ART_USE_QUICK_COMPILER