summaryrefslogtreecommitdiff
path: root/src/compiler/codegen/GenInvoke.cc
diff options
context:
space:
mode:
author buzbee <buzbee@google.com> 2012-06-13 11:12:43 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2012-06-13 11:12:43 -0700
commit1a5e1e7b3b2340a6ac08c53220900d4044ac3e4c (patch)
tree06f0041c4ff4363b1b94d3a4e8133e914fb02fa9 /src/compiler/codegen/GenInvoke.cc
parent27cac650c28bb6887b1be85fff3857c77211b294 (diff)
parent15bf9804820b73765899e4b3e0d8a1fa15e0dbd3 (diff)
Merge "More Quick compiler restructuring" into ics-mr1-plus-art
Diffstat (limited to 'src/compiler/codegen/GenInvoke.cc')
-rw-r--r--src/compiler/codegen/GenInvoke.cc291
1 files changed, 137 insertions, 154 deletions
diff --git a/src/compiler/codegen/GenInvoke.cc b/src/compiler/codegen/GenInvoke.cc
index b22cd1a16a..21ccae7940 100644
--- a/src/compiler/codegen/GenInvoke.cc
+++ b/src/compiler/codegen/GenInvoke.cc
@@ -24,7 +24,7 @@ namespace art {
* and "op" calls may be used here.
*/
-typedef int (*NextCallInsn)(CompilationUnit*, MIR*, int, uint32_t dexIdx,
+typedef int (*NextCallInsn)(CompilationUnit*, InvokeInfo*, int, uint32_t dexIdx,
uint32_t methodIdx, uintptr_t directCode,
uintptr_t directMethod, InvokeType type);
LIR* opCondBranch(CompilationUnit* cUnit, ConditionCode cc, LIR* target);
@@ -133,7 +133,7 @@ void scanMethodLiteralPool(CompilationUnit* cUnit, LIR** methodTarget, LIR** cod
* Bit of a hack here - in the absence of a real scheduling pass,
* emit the next instruction in static & direct invoke sequences.
*/
-int nextSDCallInsn(CompilationUnit* cUnit, MIR* mir,
+int nextSDCallInsn(CompilationUnit* cUnit, InvokeInfo* info,
int state, uint32_t dexIdx, uint32_t unused,
uintptr_t directCode, uintptr_t directMethod,
InvokeType type)
@@ -241,7 +241,7 @@ int nextSDCallInsn(CompilationUnit* cUnit, MIR* mir,
* Note also that we'll load the first argument ("this") into
* rARG1 here rather than the standard loadArgRegs.
*/
-int nextVCallInsn(CompilationUnit* cUnit, MIR* mir,
+int nextVCallInsn(CompilationUnit* cUnit, InvokeInfo* info,
int state, uint32_t dexIdx, uint32_t methodIdx,
uintptr_t unused, uintptr_t unused2, InvokeType unused3)
{
@@ -252,11 +252,11 @@ int nextVCallInsn(CompilationUnit* cUnit, MIR* mir,
*/
switch (state) {
case 0: // Get "this" [set rARG1]
- rlArg = oatGetSrc(cUnit, mir, 0);
+ rlArg = info->args[0];
loadValueDirectFixed(cUnit, rlArg, rARG1);
break;
case 1: // Is "this" null? [use rARG1]
- genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir->optimizationFlags);
+ genNullCheck(cUnit, info->args[0].sRegLow, rARG1, info->optFlags);
// get this->klass_ [use rARG1, set rINVOKE_TGT]
loadWordDisp(cUnit, rARG1, Object::ClassOffset().Int32Value(),
rINVOKE_TGT);
@@ -281,7 +281,7 @@ int nextVCallInsn(CompilationUnit* cUnit, MIR* mir,
return state + 1;
}
-int nextInvokeInsnSP(CompilationUnit* cUnit, MIR* mir, int trampoline,
+int nextInvokeInsnSP(CompilationUnit* cUnit, InvokeInfo* info, int trampoline,
int state, uint32_t dexIdx, uint32_t methodIdx)
{
/*
@@ -300,62 +300,63 @@ int nextInvokeInsnSP(CompilationUnit* cUnit, MIR* mir, int trampoline,
return -1;
}
-int nextStaticCallInsnSP(CompilationUnit* cUnit, MIR* mir,
+int nextStaticCallInsnSP(CompilationUnit* cUnit, InvokeInfo* info,
int state, uint32_t dexIdx, uint32_t methodIdx,
uintptr_t unused, uintptr_t unused2,
InvokeType unused3)
{
int trampoline = ENTRYPOINT_OFFSET(pInvokeStaticTrampolineWithAccessCheck);
- return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
+ return nextInvokeInsnSP(cUnit, info, trampoline, state, dexIdx, 0);
}
-int nextDirectCallInsnSP(CompilationUnit* cUnit, MIR* mir, int state,
+int nextDirectCallInsnSP(CompilationUnit* cUnit, InvokeInfo* info, int state,
uint32_t dexIdx, uint32_t methodIdx, uintptr_t unused,
uintptr_t unused2, InvokeType unused3)
{
int trampoline = ENTRYPOINT_OFFSET(pInvokeDirectTrampolineWithAccessCheck);
- return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
+ return nextInvokeInsnSP(cUnit, info, trampoline, state, dexIdx, 0);
}
-int nextSuperCallInsnSP(CompilationUnit* cUnit, MIR* mir, int state,
+int nextSuperCallInsnSP(CompilationUnit* cUnit, InvokeInfo* info, int state,
uint32_t dexIdx, uint32_t methodIdx, uintptr_t unused,
uintptr_t unused2, InvokeType unused3)
{
int trampoline = ENTRYPOINT_OFFSET(pInvokeSuperTrampolineWithAccessCheck);
- return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
+ return nextInvokeInsnSP(cUnit, info, trampoline, state, dexIdx, 0);
}
-int nextVCallInsnSP(CompilationUnit* cUnit, MIR* mir, int state,
+int nextVCallInsnSP(CompilationUnit* cUnit, InvokeInfo* info, int state,
uint32_t dexIdx, uint32_t methodIdx, uintptr_t unused,
uintptr_t unused2, InvokeType unused3)
{
int trampoline = ENTRYPOINT_OFFSET(pInvokeVirtualTrampolineWithAccessCheck);
- return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
+ return nextInvokeInsnSP(cUnit, info, trampoline, state, dexIdx, 0);
}
/*
* All invoke-interface calls bounce off of art_invoke_interface_trampoline,
* which will locate the target and continue on via a tail call.
*/
-int nextInterfaceCallInsn(CompilationUnit* cUnit, MIR* mir, int state,
+int nextInterfaceCallInsn(CompilationUnit* cUnit, InvokeInfo* info, int state,
uint32_t dexIdx, uint32_t unused, uintptr_t unused2,
uintptr_t unused3, InvokeType unused4)
{
int trampoline = ENTRYPOINT_OFFSET(pInvokeInterfaceTrampoline);
- return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
+ return nextInvokeInsnSP(cUnit, info, trampoline, state, dexIdx, 0);
}
-int nextInterfaceCallInsnWithAccessCheck(CompilationUnit* cUnit, MIR* mir,
- int state, uint32_t dexIdx,
- uint32_t unused, uintptr_t unused2,
- uintptr_t unused3, InvokeType unused4)
+int nextInterfaceCallInsnWithAccessCheck(CompilationUnit* cUnit,
+ InvokeInfo* info, int state,
+ uint32_t dexIdx, uint32_t unused,
+ uintptr_t unused2, uintptr_t unused3,
+ InvokeType unused4)
{
int trampoline = ENTRYPOINT_OFFSET(pInvokeInterfaceTrampolineWithAccessCheck);
- return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
+ return nextInvokeInsnSP(cUnit, info, trampoline, state, dexIdx, 0);
}
-int loadArgRegs(CompilationUnit* cUnit, MIR* mir, DecodedInstruction* dInsn,
- int callState, NextCallInsn nextCallInsn, uint32_t dexIdx,
+int loadArgRegs(CompilationUnit* cUnit, InvokeInfo* info, int callState,
+ NextCallInsn nextCallInsn, uint32_t dexIdx,
uint32_t methodIdx, uintptr_t directCode,
uintptr_t directMethod, InvokeType type, bool skipThis)
{
@@ -366,8 +367,8 @@ int loadArgRegs(CompilationUnit* cUnit, MIR* mir, DecodedInstruction* dInsn,
nextReg++;
nextArg++;
}
- for (; (nextReg <= lastArgReg) && (nextArg < mir->ssaRep->numUses); nextReg++) {
- RegLocation rlArg = oatGetRawSrc(cUnit, mir, nextArg++);
+ for (; (nextReg <= lastArgReg) && (nextArg < info->numArgWords); nextReg++) {
+ RegLocation rlArg = info->args[nextArg++];
rlArg = oatUpdateRawLoc(cUnit, rlArg);
if (rlArg.wide && (nextReg <= rARG2)) {
loadValueDirectWideFixed(cUnit, rlArg, nextReg, nextReg + 1);
@@ -377,7 +378,7 @@ int loadArgRegs(CompilationUnit* cUnit, MIR* mir, DecodedInstruction* dInsn,
rlArg.wide = false;
loadValueDirectFixed(cUnit, rlArg, nextReg);
}
- callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexIdx, methodIdx,
directCode, directMethod, type);
}
return callState;
@@ -390,8 +391,8 @@ int loadArgRegs(CompilationUnit* cUnit, MIR* mir, DecodedInstruction* dInsn,
* the target method pointer. Note, this may also be called
* for "range" variants if the number of arguments is 5 or fewer.
*/
-int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
- DecodedInstruction* dInsn, int callState,
+int genDalvikArgsNoRange(CompilationUnit* cUnit, InvokeInfo* info,
+ int callState,
LIR** pcrLabel, NextCallInsn nextCallInsn,
uint32_t dexIdx, uint32_t methodIdx,
uintptr_t directCode, uintptr_t directMethod,
@@ -400,19 +401,19 @@ int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
RegLocation rlArg;
/* If no arguments, just return */
- if (dInsn->vA == 0)
+ if (info->numArgWords == 0)
return callState;
- callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexIdx, methodIdx,
directCode, directMethod, type);
- DCHECK_LE(dInsn->vA, 5U);
- if (dInsn->vA > 3) {
- uint32_t nextUse = 3;
+ DCHECK_LE(info->numArgWords, 5);
+ if (info->numArgWords > 3) {
+ int32_t nextUse = 3;
//Detect special case of wide arg spanning arg3/arg4
- RegLocation rlUse0 = oatGetRawSrc(cUnit, mir, 0);
- RegLocation rlUse1 = oatGetRawSrc(cUnit, mir, 1);
- RegLocation rlUse2 = oatGetRawSrc(cUnit, mir, 2);
+ RegLocation rlUse0 = info->args[0];
+ RegLocation rlUse1 = info->args[1];
+ RegLocation rlUse2 = info->args[2];
if (((!rlUse0.wide && !rlUse1.wide) || rlUse0.wide) &&
rlUse2.wide) {
int reg = -1;
@@ -424,20 +425,20 @@ int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
// rARG2 & rARG3 can safely be used here
reg = rARG3;
loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, rlArg.sRegLow) + 4, reg);
- callState = nextCallInsn(cUnit, mir, callState, dexIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexIdx,
methodIdx, directCode, directMethod, type);
}
storeBaseDisp(cUnit, rSP, (nextUse + 1) * 4, reg, kWord);
storeBaseDisp(cUnit, rSP, 16 /* (3+1)*4 */, reg, kWord);
- callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexIdx, methodIdx,
directCode, directMethod, type);
nextUse++;
}
// Loop through the rest
- while (nextUse < dInsn->vA) {
+ while (nextUse < info->numArgWords) {
int lowReg;
int highReg = -1;
- rlArg = oatGetRawSrc(cUnit, mir, nextUse);
+ rlArg = info->args[nextUse];
rlArg = oatUpdateRawLoc(cUnit, rlArg);
if (rlArg.location == kLocPhysReg) {
lowReg = rlArg.lowReg;
@@ -450,7 +451,7 @@ int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
} else {
loadValueDirectFixed(cUnit, rlArg, lowReg);
}
- callState = nextCallInsn(cUnit, mir, callState, dexIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexIdx,
methodIdx, directCode, directMethod, type);
}
int outsOffset = (nextUse + 1) * 4;
@@ -461,18 +462,18 @@ int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
storeWordDisp(cUnit, rSP, outsOffset, lowReg);
nextUse++;
}
- callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexIdx, methodIdx,
directCode, directMethod, type);
}
}
- callState = loadArgRegs(cUnit, mir, dInsn, callState, nextCallInsn,
+ callState = loadArgRegs(cUnit, info, callState, nextCallInsn,
dexIdx, methodIdx, directCode, directMethod,
type, skipThis);
if (pcrLabel) {
- *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), rARG1,
- mir->optimizationFlags);
+ *pcrLabel = genNullCheck(cUnit, info->args[0].sRegLow, rARG1,
+ info->optFlags);
}
return callState;
}
@@ -492,40 +493,27 @@ int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
* Pass arg0, arg1 & arg2 in rARG1-rARG3
*
*/
-int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir,
- DecodedInstruction* dInsn, int callState,
+int genDalvikArgsRange(CompilationUnit* cUnit, InvokeInfo* info, int callState,
LIR** pcrLabel, NextCallInsn nextCallInsn,
uint32_t dexIdx, uint32_t methodIdx,
uintptr_t directCode, uintptr_t directMethod,
InvokeType type, bool skipThis)
{
- int firstArg = dInsn->vC;
- int numArgs = dInsn->vA;
// If we can treat it as non-range (Jumbo ops will use range form)
- if (numArgs <= 5)
- return genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pcrLabel,
+ if (info->numArgWords <= 5)
+ return genDalvikArgsNoRange(cUnit, info, callState, pcrLabel,
nextCallInsn, dexIdx, methodIdx,
directCode, directMethod, type, skipThis);
/*
- * Make sure range list doesn't span the break between in normal
- * Dalvik vRegs and the ins.
- */
- int highestArg = oatGetSrc(cUnit, mir, numArgs-1).sRegLow;
- int boundaryReg = cUnit->numDalvikRegisters - cUnit->numIns;
- if ((firstArg < boundaryReg) && (highestArg >= boundaryReg)) {
- LOG(FATAL) << "Argument list spanned locals & args";
- }
-
- /*
* First load the non-register arguments. Both forms expect all
* of the source arguments to be in their home frame location, so
* scan the sReg names and flush any that have been promoted to
* frame backing storage.
*/
// Scan the rest of the args - if in physReg flush to memory
- for (int nextArg = 0; nextArg < numArgs;) {
- RegLocation loc = oatGetRawSrc(cUnit, mir, nextArg);
+ for (int nextArg = 0; nextArg < info->numArgWords;) {
+ RegLocation loc = info->args[nextArg];
if (loc.wide) {
loc = oatUpdateLocWide(cUnit, loc);
if ((nextArg >= 2) && (loc.location == kLocPhysReg)) {
@@ -543,87 +531,81 @@ int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir,
}
}
- int startOffset = oatSRegOffset(cUnit,
- cUnit->regLocation[mir->ssaRep->uses[3]].sRegLow);
+ int startOffset = oatSRegOffset(cUnit, info->args[3].sRegLow);
int outsOffset = 4 /* Method* */ + (3 * 4);
#if defined(TARGET_MIPS) || defined(TARGET_X86)
// Generate memcpy
opRegRegImm(cUnit, kOpAdd, rARG0, rSP, outsOffset);
opRegRegImm(cUnit, kOpAdd, rARG1, rSP, startOffset);
callRuntimeHelperRegRegImm(cUnit, ENTRYPOINT_OFFSET(pMemcpy),
- rARG0, rARG1, (numArgs - 3) * 4);
+ rARG0, rARG1, (info->numArgWords - 3) * 4);
#else
- if (numArgs >= 20) {
+ if (info->numArgWords >= 20) {
// Generate memcpy
opRegRegImm(cUnit, kOpAdd, rARG0, rSP, outsOffset);
opRegRegImm(cUnit, kOpAdd, rARG1, rSP, startOffset);
callRuntimeHelperRegRegImm(cUnit, ENTRYPOINT_OFFSET(pMemcpy),
- rARG0, rARG1, (numArgs - 3) * 4);
+ rARG0, rARG1, (info->numArgWords - 3) * 4);
} else {
// Use vldm/vstm pair using rARG3 as a temp
- int regsLeft = std::min(numArgs - 3, 16);
- callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
+ int regsLeft = std::min(info->numArgWords - 3, 16);
+ callState = nextCallInsn(cUnit, info, callState, dexIdx, methodIdx,
directCode, directMethod, type);
opRegRegImm(cUnit, kOpAdd, rARG3, rSP, startOffset);
LIR* ld = newLIR3(cUnit, kThumb2Vldms, rARG3, fr0, regsLeft);
//TUNING: loosen barrier
ld->defMask = ENCODE_ALL;
setMemRefType(ld, true /* isLoad */, kDalvikReg);
- callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexIdx, methodIdx,
directCode, directMethod, type);
opRegRegImm(cUnit, kOpAdd, rARG3, rSP, 4 /* Method* */ + (3 * 4));
- callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexIdx, methodIdx,
directCode, directMethod, type);
LIR* st = newLIR3(cUnit, kThumb2Vstms, rARG3, fr0, regsLeft);
setMemRefType(st, false /* isLoad */, kDalvikReg);
st->defMask = ENCODE_ALL;
- callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexIdx, methodIdx,
directCode, directMethod, type);
}
#endif
- callState = loadArgRegs(cUnit, mir, dInsn, callState, nextCallInsn,
+ callState = loadArgRegs(cUnit, info, callState, nextCallInsn,
dexIdx, methodIdx, directCode, directMethod,
type, skipThis);
- callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexIdx, methodIdx,
directCode, directMethod, type);
if (pcrLabel) {
- *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), rARG1,
- mir->optimizationFlags);
+ *pcrLabel = genNullCheck(cUnit, info->args[0].sRegLow, rARG1,
+ info->optFlags);
}
return callState;
}
-RegLocation inlineTarget(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
+RegLocation inlineTarget(CompilationUnit* cUnit, InvokeInfo* info)
{
RegLocation res;
- mir = oatFindMoveResult(cUnit, bb, mir, false);
- if (mir == NULL) {
+ if (info->result.location == kLocInvalid) {
res = oatGetReturn(cUnit, false);
} else {
- res = oatGetDest(cUnit, mir, 0);
- mir->dalvikInsn.opcode = Instruction::NOP;
+ res = info->result;
}
return res;
}
-RegLocation inlineTargetWide(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
+RegLocation inlineTargetWide(CompilationUnit* cUnit, InvokeInfo* info)
{
RegLocation res;
- mir = oatFindMoveResult(cUnit, bb, mir, true);
- if (mir == NULL) {
+ if (info->result.location == kLocInvalid) {
res = oatGetReturnWide(cUnit, false);
} else {
- res = oatGetDestWide(cUnit, mir, 0, 1);
- mir->dalvikInsn.opcode = Instruction::NOP;
+ res = info->result;
}
return res;
}
-bool genInlinedCharAt(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- InvokeType type, bool isRange)
+bool genInlinedCharAt(CompilationUnit* cUnit, InvokeInfo* info)
{
#if defined(TARGET_ARM)
// Location of reference to data array
@@ -635,15 +617,15 @@ bool genInlinedCharAt(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
// Start of char data with array_
int dataOffset = Array::DataOffset(sizeof(uint16_t)).Int32Value();
- RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
- RegLocation rlIdx = oatGetSrc(cUnit, mir, 1);
+ RegLocation rlObj = info->args[0];
+ RegLocation rlIdx = info->args[1];
rlObj = loadValue(cUnit, rlObj, kCoreReg);
rlIdx = loadValue(cUnit, rlIdx, kCoreReg);
int regMax;
int regOff = oatAllocTemp(cUnit);
int regPtr = oatAllocTemp(cUnit);
- genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->optimizationFlags);
- bool rangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
+ genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, info->optFlags);
+ bool rangeCheck = (!(info->optFlags & MIR_IGNORE_RANGE_CHECK));
if (rangeCheck) {
regMax = oatAllocTemp(cUnit);
loadWordDisp(cUnit, rlObj.lowReg, countOffset, regMax);
@@ -653,7 +635,7 @@ bool genInlinedCharAt(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
LIR* launchPad = NULL;
if (rangeCheck) {
// Set up a launch pad to allow retry in case of bounds violation */
- launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
+ launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (uintptr_t)info);
oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
(intptr_t)launchPad);
opRegReg(cUnit, kOpCmp, rlIdx.lowReg, regMax);
@@ -662,7 +644,7 @@ bool genInlinedCharAt(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
}
opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
opRegReg(cUnit, kOpAdd, regOff, rlIdx.lowReg);
- RegLocation rlDest = inlineTarget(cUnit, bb, mir);
+ RegLocation rlDest = inlineTarget(cUnit, info);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
loadBaseIndexed(cUnit, regPtr, regOff, rlResult.lowReg, 1, kUnsignedHalf);
oatFreeTemp(cUnit, regOff);
@@ -670,25 +652,23 @@ bool genInlinedCharAt(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
storeValue(cUnit, rlDest, rlResult);
if (rangeCheck) {
launchPad->operands[2] = 0; // no resumption
- launchPad->operands[3] = (uintptr_t)bb;
}
// Record that we've already inlined & null checked
- mir->optimizationFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
+ info->optFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
return true;
#else
return false;
#endif
}
-bool genInlinedMinMaxInt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir,
- bool isMin)
+bool genInlinedMinMaxInt(CompilationUnit *cUnit, InvokeInfo* info, bool isMin)
{
#if defined(TARGET_ARM)
- RegLocation rlSrc1 = oatGetSrc(cUnit, mir, 0);
- RegLocation rlSrc2 = oatGetSrc(cUnit, mir, 1);
+ RegLocation rlSrc1 = info->args[0];
+ RegLocation rlSrc2 = info->args[1];
rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
- RegLocation rlDest = inlineTarget(cUnit, bb, mir);
+ RegLocation rlDest = inlineTarget(cUnit, info);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
opIT(cUnit, (isMin) ? kArmCondGt : kArmCondLt, "E");
@@ -703,16 +683,16 @@ bool genInlinedMinMaxInt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir,
}
// Generates an inlined String.isEmpty or String.length.
-bool genInlinedStringIsEmptyOrLength(CompilationUnit* cUnit,
- BasicBlock* bb, MIR* mir, bool isEmpty)
+bool genInlinedStringIsEmptyOrLength(CompilationUnit* cUnit, InvokeInfo* info,
+ bool isEmpty)
{
#if defined(TARGET_ARM)
// dst = src.length();
- RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
+ RegLocation rlObj = info->args[0];
rlObj = loadValue(cUnit, rlObj, kCoreReg);
- RegLocation rlDest = inlineTarget(cUnit, bb, mir);
+ RegLocation rlDest = inlineTarget(cUnit, info);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
- genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->optimizationFlags);
+ genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, info->optFlags);
loadWordDisp(cUnit, rlObj.lowReg, String::CountOffset().Int32Value(),
rlResult.lowReg);
if (isEmpty) {
@@ -728,12 +708,12 @@ bool genInlinedStringIsEmptyOrLength(CompilationUnit* cUnit,
#endif
}
-bool genInlinedAbsInt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
+bool genInlinedAbsInt(CompilationUnit *cUnit, InvokeInfo* info)
{
#if defined(TARGET_ARM)
- RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
+ RegLocation rlSrc = info->args[0];
rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
- RegLocation rlDest = inlineTarget(cUnit, bb, mir);
+ RegLocation rlDest = inlineTarget(cUnit, info);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
int signReg = oatAllocTemp(cUnit);
// abs(x) = y<=x>>31, (x+y)^y.
@@ -747,12 +727,12 @@ bool genInlinedAbsInt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
#endif
}
-bool genInlinedAbsLong(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
+bool genInlinedAbsLong(CompilationUnit *cUnit, InvokeInfo* info)
{
#if defined(TARGET_ARM)
- RegLocation rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+ RegLocation rlSrc = info->args[0];
rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
- RegLocation rlDest = inlineTargetWide(cUnit, bb, mir);
+ RegLocation rlDest = inlineTargetWide(cUnit, info);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
int signReg = oatAllocTemp(cUnit);
// abs(x) = y<=x>>31, (x+y)^y.
@@ -768,11 +748,11 @@ bool genInlinedAbsLong(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
#endif
}
-bool genInlinedFloatCvt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
+bool genInlinedFloatCvt(CompilationUnit *cUnit, InvokeInfo* info)
{
#if defined(TARGET_ARM)
- RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
- RegLocation rlDest = inlineTarget(cUnit, bb, mir);
+ RegLocation rlSrc = info->args[0];
+ RegLocation rlDest = inlineTarget(cUnit, info);
storeValue(cUnit, rlDest, rlSrc);
return true;
#else
@@ -780,11 +760,11 @@ bool genInlinedFloatCvt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
#endif
}
-bool genInlinedDoubleCvt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
+bool genInlinedDoubleCvt(CompilationUnit *cUnit, InvokeInfo* info)
{
#if defined(TARGET_ARM)
- RegLocation rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
- RegLocation rlDest = inlineTargetWide(cUnit, bb, mir);
+ RegLocation rlSrc = info->args[0];
+ RegLocation rlDest = inlineTargetWide(cUnit, info);
storeValueWide(cUnit, rlDest, rlSrc);
return true;
#else
@@ -796,8 +776,8 @@ bool genInlinedDoubleCvt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
* Fast string.indexOf(I) & (II). Tests for simple case of char <= 0xffff,
* otherwise bails to standard library code.
*/
-bool genInlinedIndexOf(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- InvokeType type, bool zeroBased)
+bool genInlinedIndexOf(CompilationUnit* cUnit, InvokeInfo* info,
+ bool zeroBased)
{
#if defined(TARGET_ARM)
@@ -807,9 +787,9 @@ bool genInlinedIndexOf(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
int regChar = rARG1;
int regStart = rARG2;
- RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
- RegLocation rlChar = oatGetSrc(cUnit, mir, 1);
- RegLocation rlStart = oatGetSrc(cUnit, mir, 2);
+ RegLocation rlObj = info->args[0];
+ RegLocation rlChar = info->args[1];
+ RegLocation rlStart = info->args[2];
loadValueDirectFixed(cUnit, rlObj, regPtr);
loadValueDirectFixed(cUnit, rlChar, regChar);
if (zeroBased) {
@@ -818,17 +798,19 @@ bool genInlinedIndexOf(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
loadValueDirectFixed(cUnit, rlStart, regStart);
}
int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pIndexOf));
- genNullCheck(cUnit, rlObj.sRegLow, regPtr, mir->optimizationFlags);
- LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
+ genNullCheck(cUnit, rlObj.sRegLow, regPtr, info->optFlags);
+ LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (uintptr_t)info);
oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
(intptr_t)launchPad);
opCmpImmBranch(cUnit, kCondGt, regChar, 0xFFFF, launchPad);
opReg(cUnit, kOpBlx, rTgt);
LIR* resumeTgt = newLIR0(cUnit, kPseudoTargetLabel);
launchPad->operands[2] = (uintptr_t)resumeTgt;
- launchPad->operands[3] = (uintptr_t)bb;
// Record that we've already inlined & null checked
- mir->optimizationFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
+ info->optFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
+ RegLocation rlReturn = oatGetReturn(cUnit, false);
+ RegLocation rlDest = inlineTarget(cUnit, info);
+ storeValue(cUnit, rlDest, rlReturn);
return true;
#else
return false;
@@ -836,8 +818,7 @@ bool genInlinedIndexOf(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
}
/* Fast string.compareTo(Ljava/lang/string;)I. */
-bool genInlinedStringCompareTo(CompilationUnit* cUnit, BasicBlock* bb,
- MIR* mir, InvokeType type)
+bool genInlinedStringCompareTo(CompilationUnit* cUnit, InvokeInfo* info)
{
#if defined(TARGET_ARM)
oatClobberCalleeSave(cUnit);
@@ -845,32 +826,34 @@ bool genInlinedStringCompareTo(CompilationUnit* cUnit, BasicBlock* bb,
int regThis = rARG0;
int regCmp = rARG1;
- RegLocation rlThis = oatGetSrc(cUnit, mir, 0);
- RegLocation rlCmp = oatGetSrc(cUnit, mir, 1);
+ RegLocation rlThis = info->args[0];
+ RegLocation rlCmp = info->args[1];
loadValueDirectFixed(cUnit, rlThis, regThis);
loadValueDirectFixed(cUnit, rlCmp, regCmp);
int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pStringCompareTo));
- genNullCheck(cUnit, rlThis.sRegLow, regThis, mir->optimizationFlags);
+ genNullCheck(cUnit, rlThis.sRegLow, regThis, info->optFlags);
//TUNING: check if rlCmp.sRegLow is already null checked
- LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
+ LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (uintptr_t)info);
oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
(intptr_t)launchPad);
opCmpImmBranch(cUnit, kCondEq, regCmp, 0, launchPad);
opReg(cUnit, kOpBlx, rTgt);
launchPad->operands[2] = 0; // No return possible
- launchPad->operands[3] = (uintptr_t)bb;
// Record that we've already inlined & null checked
- mir->optimizationFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
+ info->optFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
+ RegLocation rlReturn = oatGetReturn(cUnit, false);
+ RegLocation rlDest = inlineTarget(cUnit, info);
+ storeValue(cUnit, rlDest, rlReturn);
return true;
#else
return false;
#endif
}
-bool genIntrinsic(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- InvokeType type, bool isRange)
+bool genIntrinsic(CompilationUnit* cUnit, InvokeInfo* info)
{
- if ((mir->optimizationFlags & MIR_INLINED) || isRange) {
+ if ((info->optFlags & MIR_INLINED) || info->isRange ||
+ (info->result.location == kLocInvalid)) {
return false;
}
/*
@@ -883,48 +866,48 @@ bool genIntrinsic(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
* method. By doing this during basic block construction, we can also
* take advantage of/generate new useful dataflow info.
*/
- std::string tgtMethod(PrettyMethod(mir->dalvikInsn.vB, *cUnit->dex_file));
+ std::string tgtMethod(PrettyMethod(info->methodIdx, *cUnit->dex_file));
if (tgtMethod.compare("char java.lang.String.charAt(int)") == 0) {
- return genInlinedCharAt(cUnit, bb, mir, type, isRange);
+ return genInlinedCharAt(cUnit, info);
}
if (tgtMethod.compare("int java.lang.Math.min(int, int)") == 0) {
- return genInlinedMinMaxInt(cUnit, bb, mir, true /* isMin */);
+ return genInlinedMinMaxInt(cUnit, info, true /* isMin */);
}
if (tgtMethod.compare("int java.lang.Math.max(int, int)") == 0) {
- return genInlinedMinMaxInt(cUnit, bb, mir, false /* isMin */);
+ return genInlinedMinMaxInt(cUnit, info, false /* isMin */);
}
if (tgtMethod.compare("int java.lang.String.length()") == 0) {
- return genInlinedStringIsEmptyOrLength(cUnit, bb, mir, false /* isEmpty */);
+ return genInlinedStringIsEmptyOrLength(cUnit, info, false /* isEmpty */);
}
if (tgtMethod.compare("boolean java.lang.String.isEmpty()") == 0) {
- return genInlinedStringIsEmptyOrLength(cUnit, bb, mir, true /* isEmpty */);
+ return genInlinedStringIsEmptyOrLength(cUnit, info, true /* isEmpty */);
}
if (tgtMethod.compare("int java.lang.Math.abs(int)") == 0) {
- return genInlinedAbsInt(cUnit, bb, mir);
+ return genInlinedAbsInt(cUnit, info);
}
if (tgtMethod.compare("long java.lang.Math.abs(long)") == 0) {
- return genInlinedAbsLong(cUnit, bb, mir);
+ return genInlinedAbsLong(cUnit, info);
}
if (tgtMethod.compare("int java.lang.Float.floatToRawIntBits(float)") == 0) {
- return genInlinedFloatCvt(cUnit, bb, mir);
+ return genInlinedFloatCvt(cUnit, info);
}
if (tgtMethod.compare("float java.lang.Float.intBitsToFloat(int)") == 0) {
- return genInlinedFloatCvt(cUnit, bb, mir);
+ return genInlinedFloatCvt(cUnit, info);
}
if (tgtMethod.compare("long java.lang.Double.doubleToRawLongBits(double)") == 0) {
- return genInlinedDoubleCvt(cUnit, bb, mir);
+ return genInlinedDoubleCvt(cUnit, info);
}
if (tgtMethod.compare("double java.lang.Double.longBitsToDouble(long)") == 0) {
- return genInlinedDoubleCvt(cUnit, bb, mir);
+ return genInlinedDoubleCvt(cUnit, info);
}
if (tgtMethod.compare("int java.lang.String.indexOf(int, int)") == 0) {
- return genInlinedIndexOf(cUnit, bb, mir, type, false /* base 0 */);
+ return genInlinedIndexOf(cUnit, info, false /* base 0 */);
}
if (tgtMethod.compare("int java.lang.String.indexOf(int)") == 0) {
- return genInlinedIndexOf(cUnit, bb, mir, type, true /* base 0 */);
+ return genInlinedIndexOf(cUnit, info, true /* base 0 */);
}
if (tgtMethod.compare("int java.lang.String.compareTo(java.lang.String)") == 0) {
- return genInlinedStringCompareTo(cUnit, bb, mir, type);
+ return genInlinedStringCompareTo(cUnit, info);
}
return false;
}