summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/CompilerIR.h19
-rw-r--r--src/compiler/Dataflow.cc9
-rw-r--r--src/compiler/Ralloc.cc1
-rw-r--r--src/compiler/codegen/GenCommon.cc11
-rw-r--r--src/compiler/codegen/GenInvoke.cc291
-rw-r--r--src/compiler/codegen/MethodBitcode.cc12
-rw-r--r--src/compiler/codegen/MethodCodegenDriver.cc108
-rw-r--r--src/compiler/codegen/Ralloc.h11
-rw-r--r--src/compiler/codegen/RallocUtil.cc32
-rw-r--r--src/compiler/codegen/arm/FP/Thumb2VFP.cc4
-rw-r--r--src/compiler/codegen/arm/Thumb2/Gen.cc8
11 files changed, 274 insertions, 232 deletions
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index e9a26562e2..5b92af1bc5 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -84,6 +84,22 @@ struct CompilerTemp {
ArenaBitVector* bv;
};
+struct InvokeInfo {
+ int numArgWords; // Note: word count, not arg count
+ RegLocation* args; // One for each word of arguments
+ RegLocation result; // Eventual target of MOVE_RESULT
+ int optFlags;
+ InvokeType type;
+ uint32_t dexIdx;
+ uint32_t methodIdx;
+ uintptr_t directCode;
+ uintptr_t directMethod;
+ RegLocation target; // Target of following move_result
+ bool skipThis;
+ bool isRange;
+ int offset; // Dalvik offset
+};
+
/*
* Data structure tracking the mapping between a Dalvik register (pair) and a
* native register (pair). The idea is to reuse the previously loaded value
@@ -755,8 +771,7 @@ void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
-MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- bool wide);
+MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
/* Debug Utilities */
void oatDumpCompilationUnit(CompilationUnit* cUnit);
diff --git a/src/compiler/Dataflow.cc b/src/compiler/Dataflow.cc
index 3483d5bc45..8196ce9ebd 100644
--- a/src/compiler/Dataflow.cc
+++ b/src/compiler/Dataflow.cc
@@ -1683,16 +1683,13 @@ MIR* advanceMIR(CompilationUnit* cUnit, BasicBlock** pBb, MIR* mir,
* opcodes or incoming arcs. However, if the result of the invoke is not
* used, a move-result may not be present.
*/
-MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- bool wide)
+MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
{
BasicBlock* tbb = bb;
mir = advanceMIR(cUnit, &tbb, mir, NULL, false);
while (mir != NULL) {
- if (!wide && mir->dalvikInsn.opcode == Instruction::MOVE_RESULT) {
- break;
- }
- if (wide && mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE) {
+ if ((mir->dalvikInsn.opcode == Instruction::MOVE_RESULT) ||
+ (mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE)) {
break;
}
// Keep going if pseudo op, otherwise terminate
diff --git a/src/compiler/Ralloc.cc b/src/compiler/Ralloc.cc
index bc0c6dec80..e1689a6840 100644
--- a/src/compiler/Ralloc.cc
+++ b/src/compiler/Ralloc.cc
@@ -86,6 +86,7 @@ SSARepresentation* findMoveResult(MIR* mir)
SSARepresentation* res = NULL;
for (; mir; mir = mir->next) {
if ((mir->dalvikInsn.opcode == Instruction::MOVE_RESULT) ||
+ (mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_OBJECT) ||
(mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE)) {
res = mir->ssaRep;
break;
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 2bd93331a6..2ca90466ee 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -23,8 +23,7 @@ namespace art {
* be applicable to most targets. Only mid-level support utilities
* and "op" calls may be used here.
*/
-void genInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- InvokeType type, bool isRange);
+void genInvoke(CompilationUnit* cUnit, InvokeInfo* info);
#if defined(TARGET_ARM)
LIR* opIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide);
bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode,
@@ -870,12 +869,10 @@ void handleIntrinsicLaunchpads(CompilationUnit *cUnit)
oatResetRegPool(cUnit);
oatResetDefTracking(cUnit);
LIR* lab = intrinsicLabel[i];
- MIR* mir = (MIR*)lab->operands[0];
- InvokeType type = (InvokeType)lab->operands[1];
- BasicBlock* bb = (BasicBlock*)lab->operands[3];
- cUnit->currentDalvikOffset = mir->offset;
+ InvokeInfo* info = (InvokeInfo*)lab->operands[0];
+ cUnit->currentDalvikOffset = info->offset;
oatAppendLIR(cUnit, lab);
- genInvoke(cUnit, bb, mir, type, false /* isRange */);
+ genInvoke(cUnit, info);
LIR* resumeLab = (LIR*)lab->operands[2];
if (resumeLab != NULL) {
opUnconditionalBranch(cUnit, resumeLab);
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;
}
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index 4ada78cfb0..3b6b087e8d 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -336,7 +336,7 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
if (attrs & DF_UA) {
if (attrs & DF_A_WIDE) {
- rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg, nextSreg + 1);
+ rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
nextSreg+= 2;
} else {
rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
@@ -345,7 +345,7 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
}
if (attrs & DF_UB) {
if (attrs & DF_B_WIDE) {
- rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg, nextSreg + 1);
+ rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
nextSreg+= 2;
} else {
rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
@@ -354,16 +354,16 @@ bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
}
if (attrs & DF_UC) {
if (attrs & DF_C_WIDE) {
- rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg, nextSreg + 1);
+ rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
} else {
rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
}
}
if (attrs & DF_DA) {
if (attrs & DF_A_WIDE) {
- rlDest = oatGetDestWide(cUnit, mir, 0, 1);
+ rlDest = oatGetDestWide(cUnit, mir);
} else {
- rlDest = oatGetDest(cUnit, mir, 0);
+ rlDest = oatGetDest(cUnit, mir);
if (rlDest.ref) {
objectDefinition = true;
}
@@ -993,7 +993,7 @@ void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
for (int i = 0; i < mir->ssaRep->numUses; i++) {
RegLocation loc;
if (rlDest.wide) {
- loc = oatGetSrcWide(cUnit, mir, i, i+1);
+ loc = oatGetSrcWide(cUnit, mir, i);
i++;
} else {
loc = oatGetSrc(cUnit, mir, i);
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index 15dbeddca6..1707a8992c 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -53,14 +53,12 @@ RegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat)
return res;
}
-void genInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- InvokeType type, bool isRange)
+void genInvoke(CompilationUnit* cUnit, InvokeInfo* info)
{
- if (genIntrinsic(cUnit, bb, mir, type, isRange)) {
+ if (genIntrinsic(cUnit, info)) {
return;
}
- DecodedInstruction* dInsn = &mir->dalvikInsn;
- InvokeType originalType = type; // avoiding mutation by ComputeInvokeInfo
+ InvokeType originalType = info->type; // avoiding mutation by ComputeInvokeInfo
int callState = 0;
LIR* nullCk;
LIR** pNullCk = NULL;
@@ -74,52 +72,52 @@ void genInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
cUnit->code_item, cUnit->method_idx,
cUnit->access_flags);
- uint32_t dexMethodIdx = dInsn->vB;
+ uint32_t dexMethodIdx = info->methodIdx;
int vtableIdx;
uintptr_t directCode;
uintptr_t directMethod;
bool skipThis;
bool fastPath =
- cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, type,
+ cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, info->type,
vtableIdx, directCode,
directMethod)
&& !SLOW_INVOKE_PATH;
- if (type == kInterface) {
+ if (info->type == kInterface) {
nextCallInsn = fastPath ? nextInterfaceCallInsn
: nextInterfaceCallInsnWithAccessCheck;
skipThis = false;
- } else if (type == kDirect) {
+ } else if (info->type == kDirect) {
if (fastPath) {
pNullCk = &nullCk;
}
nextCallInsn = fastPath ? nextSDCallInsn : nextDirectCallInsnSP;
skipThis = false;
- } else if (type == kStatic) {
+ } else if (info->type == kStatic) {
nextCallInsn = fastPath ? nextSDCallInsn : nextStaticCallInsnSP;
skipThis = false;
- } else if (type == kSuper) {
+ } else if (info->type == kSuper) {
DCHECK(!fastPath); // Fast path is a direct call.
nextCallInsn = nextSuperCallInsnSP;
skipThis = false;
} else {
- DCHECK_EQ(type, kVirtual);
+ DCHECK_EQ(info->type, kVirtual);
nextCallInsn = fastPath ? nextVCallInsn : nextVCallInsnSP;
skipThis = fastPath;
}
- if (!isRange) {
- callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pNullCk,
+ if (!info->isRange) {
+ callState = genDalvikArgsNoRange(cUnit, info, callState, pNullCk,
nextCallInsn, dexMethodIdx,
vtableIdx, directCode, directMethod,
originalType, skipThis);
} else {
- callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, pNullCk,
+ callState = genDalvikArgsRange(cUnit, info, callState, pNullCk,
nextCallInsn, dexMethodIdx, vtableIdx,
directCode, directMethod, originalType,
skipThis);
}
// Finish up any of the call sequence not interleaved in arg loading
while (callState >= 0) {
- callState = nextCallInsn(cUnit, mir, callState, dexMethodIdx,
+ callState = nextCallInsn(cUnit, info, callState, dexMethodIdx,
vtableIdx, directCode, directMethod,
originalType);
}
@@ -129,11 +127,11 @@ void genInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
#if !defined(TARGET_X86)
opReg(cUnit, kOpBlx, rINVOKE_TGT);
#else
- if (fastPath && type != kInterface) {
+ if (fastPath && info->type != kInterface) {
opMem(cUnit, kOpBlx, rARG0, Method::GetCodeOffset().Int32Value());
} else {
int trampoline = 0;
- switch (type) {
+ switch (info->type) {
case kInterface:
trampoline = fastPath ? ENTRYPOINT_OFFSET(pInvokeInterfaceTrampoline)
: ENTRYPOINT_OFFSET(pInvokeInterfaceTrampolineWithAccessCheck);
@@ -158,6 +156,48 @@ void genInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
#endif
oatClobberCalleeSave(cUnit);
+ if (info->result.location != kLocInvalid) {
+ // We have a following MOVE_RESULT - do it now.
+ if (info->result.wide) {
+ RegLocation retLoc = oatGetReturnWide(cUnit, false);
+ storeValueWide(cUnit, info->result, retLoc);
+ } else {
+ RegLocation retLoc = oatGetReturn(cUnit, false);
+ storeValue(cUnit, info->result, retLoc);
+ }
+ }
+}
+
+/*
+ * Build an array of location records for the incoming arguments.
+ * Note: one location record per word of arguments, with dummy
+ * high-word loc for wide arguments. Also pull up any following
+ * MOVE_RESULT and incorporate it into the invoke.
+ */
+InvokeInfo* newInvokeInfo(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+ InvokeType type, bool isRange)
+{
+ InvokeInfo* info = (InvokeInfo*)oatNew(cUnit, sizeof(InvokeInfo), true,
+ kAllocMisc);
+ MIR* moveResultMIR = oatFindMoveResult(cUnit, bb, mir);
+ if (moveResultMIR == NULL) {
+ info->result.location = kLocInvalid;
+ } else {
+ info->result = oatGetRawDest(cUnit, moveResultMIR);
+ moveResultMIR->dalvikInsn.opcode = Instruction::NOP;
+ }
+ info->numArgWords = mir->ssaRep->numUses;
+ info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
+ oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
+ for (int i = 0; i < info->numArgWords; i++) {
+ info->args[i] = oatGetRawSrc(cUnit, mir, i);
+ }
+ info->optFlags = mir->optimizationFlags;
+ info->type = type;
+ info->isRange = isRange;
+ info->methodIdx = mir->dalvikInsn.vB;
+ info->offset = mir->offset;
+ return info;
}
/*
@@ -185,7 +225,7 @@ bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
if (attrs & DF_UA) {
if (attrs & DF_A_WIDE) {
- rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg, nextSreg + 1);
+ rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
nextSreg+= 2;
} else {
rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
@@ -194,7 +234,7 @@ bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
}
if (attrs & DF_UB) {
if (attrs & DF_B_WIDE) {
- rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg, nextSreg + 1);
+ rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
nextSreg+= 2;
} else {
rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
@@ -203,16 +243,16 @@ bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
}
if (attrs & DF_UC) {
if (attrs & DF_C_WIDE) {
- rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg, nextSreg + 1);
+ rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
} else {
rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
}
}
if (attrs & DF_DA) {
if (attrs & DF_A_WIDE) {
- rlDest = oatGetDestWide(cUnit, mir, 0, 1);
+ rlDest = oatGetDestWide(cUnit, mir);
} else {
- rlDest = oatGetDest(cUnit, mir, 0);
+ rlDest = oatGetDest(cUnit, mir);
}
}
switch (opcode) {
@@ -570,38 +610,38 @@ bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
break;
case Instruction::INVOKE_STATIC_RANGE:
- genInvoke(cUnit, bb, mir, kStatic, true /*range*/);
+ genInvoke(cUnit, newInvokeInfo(cUnit, bb, mir, kStatic, true));
break;
case Instruction::INVOKE_STATIC:
- genInvoke(cUnit, bb, mir, kStatic, false /*range*/);
+ genInvoke(cUnit, newInvokeInfo(cUnit, bb, mir, kStatic, false));
break;
case Instruction::INVOKE_DIRECT:
- genInvoke(cUnit, bb, mir, kDirect, false /*range*/);
+ genInvoke(cUnit, newInvokeInfo(cUnit, bb, mir, kDirect, false));
break;
case Instruction::INVOKE_DIRECT_RANGE:
- genInvoke(cUnit, bb, mir, kDirect, true /*range*/);
+ genInvoke(cUnit, newInvokeInfo(cUnit, bb, mir, kDirect, true));
break;
case Instruction::INVOKE_VIRTUAL:
- genInvoke(cUnit, bb, mir, kVirtual, false /*range*/);
+ genInvoke(cUnit, newInvokeInfo(cUnit, bb, mir, kVirtual, false));
break;
case Instruction::INVOKE_VIRTUAL_RANGE:
- genInvoke(cUnit, bb, mir, kVirtual, true /*range*/);
+ genInvoke(cUnit, newInvokeInfo(cUnit, bb, mir, kVirtual, true));
break;
case Instruction::INVOKE_SUPER:
- genInvoke(cUnit, bb, mir, kSuper, false /*range*/);
+ genInvoke(cUnit, newInvokeInfo(cUnit, bb, mir, kSuper, false));
break;
case Instruction::INVOKE_SUPER_RANGE:
- genInvoke(cUnit, bb, mir, kSuper, true /*range*/);
+ genInvoke(cUnit, newInvokeInfo(cUnit, bb, mir, kSuper, true));
break;
case Instruction::INVOKE_INTERFACE:
- genInvoke(cUnit, bb, mir, kInterface, false /*range*/);
+ genInvoke(cUnit, newInvokeInfo(cUnit, bb, mir, kInterface, false));
break;
case Instruction::INVOKE_INTERFACE_RANGE:
- genInvoke(cUnit, bb, mir, kInterface, true /*range*/);
+ genInvoke(cUnit, newInvokeInfo(cUnit, bb, mir, kInterface, true));
break;
case Instruction::NEG_INT:
@@ -796,7 +836,7 @@ void handleExtendedMethodMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
}
case kMirOpCopy: {
RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
- RegLocation rlDest = oatGetDest(cUnit, mir, 0);
+ RegLocation rlDest = oatGetDest(cUnit, mir);
storeValue(cUnit, rlDest, rlSrc);
break;
}
diff --git a/src/compiler/codegen/Ralloc.h b/src/compiler/codegen/Ralloc.h
index c0b60689a0..8c3887a944 100644
--- a/src/compiler/codegen/Ralloc.h
+++ b/src/compiler/codegen/Ralloc.h
@@ -107,17 +107,18 @@ extern void oatMarkDef(CompilationUnit* cUnit, RegLocation rl, LIR* start,
extern void oatMarkDefWide(CompilationUnit* cUnit, RegLocation rl,
LIR* start, LIR* finish);
-extern RegLocation oatGetSrcWide(CompilationUnit* cUnit, MIR* mir,
- int low, int high);
-extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir,
- int low, int high);
// Get the LocRecord associated with an SSA name use.
extern RegLocation oatGetSrc(CompilationUnit* cUnit, MIR* mir, int num);
+extern RegLocation oatGetSrcWide(CompilationUnit* cUnit, MIR* mir, int low);
+// Non-width checking version
extern RegLocation oatGetRawSrc(CompilationUnit* cUnit, MIR* mir, int num);
// Get the LocRecord associated with an SSA name def.
-extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir, int num);
+extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir);
+extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir);
+// Non-width checking version
+extern RegLocation oatGetRawDest(CompilationUnit* cUnit, MIR* mir);
extern RegLocation oatGetReturnWide(CompilationUnit* cUnit, bool isDouble);
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc
index 14b4159963..e2f2cd683b 100644
--- a/src/compiler/codegen/RallocUtil.cc
+++ b/src/compiler/codegen/RallocUtil.cc
@@ -1005,35 +1005,43 @@ extern RegLocation oatEvalLoc(CompilationUnit* cUnit, RegLocation loc,
return loc;
}
-extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir, int num)
+extern RegLocation oatGetRawSrc(CompilationUnit* cUnit, MIR* mir, int num)
{
- RegLocation res = cUnit->regLocation[mir->ssaRep->defs[num]];
- DCHECK(!res.wide);
+ DCHECK(num < mir->ssaRep->numUses);
+ RegLocation res = cUnit->regLocation[mir->ssaRep->uses[num]];
+ DCHECK(!res.wide || num < (mir->ssaRep->numUses - 1));
return res;
}
-extern RegLocation oatGetSrc(CompilationUnit* cUnit, MIR* mir, int num)
+extern RegLocation oatGetRawDest(CompilationUnit* cUnit, MIR* mir)
{
- RegLocation res = cUnit->regLocation[mir->ssaRep->uses[num]];
+ DCHECK(mir->ssaRep->numDefs > 0);
+ RegLocation res = cUnit->regLocation[mir->ssaRep->defs[0]];
+ DCHECK(!res.wide || mir->ssaRep->numDefs == 2);
+ return res;
+}
+extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir)
+{
+ RegLocation res = oatGetRawDest(cUnit, mir);
DCHECK(!res.wide);
return res;
}
-extern RegLocation oatGetRawSrc(CompilationUnit* cUnit, MIR* mir, int num)
+extern RegLocation oatGetSrc(CompilationUnit* cUnit, MIR* mir, int num)
{
- RegLocation res = cUnit->regLocation[mir->ssaRep->uses[num]];
+ RegLocation res = oatGetRawSrc(cUnit, mir, num);
+ DCHECK(!res.wide);
return res;
}
-extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir,
- int low, int high)
+extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir)
{
- RegLocation res = cUnit->regLocation[mir->ssaRep->defs[low]];
+ RegLocation res = oatGetRawDest(cUnit, mir);
DCHECK(res.wide);
return res;
}
extern RegLocation oatGetSrcWide(CompilationUnit* cUnit, MIR* mir,
- int low, int high)
+ int low)
{
- RegLocation res = cUnit->regLocation[mir->ssaRep->uses[low]];
+ RegLocation res = oatGetRawSrc(cUnit, mir, low);
DCHECK(res.wide);
return res;
}
diff --git a/src/compiler/codegen/arm/FP/Thumb2VFP.cc b/src/compiler/codegen/arm/FP/Thumb2VFP.cc
index fb14aeccb7..1b67ecba53 100644
--- a/src/compiler/codegen/arm/FP/Thumb2VFP.cc
+++ b/src/compiler/codegen/arm/FP/Thumb2VFP.cc
@@ -167,8 +167,8 @@ void genFusedFPCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
RegLocation rlSrc1;
RegLocation rlSrc2;
if (isDouble) {
- rlSrc1 = oatGetSrcWide(cUnit, mir, 0, 1);
- rlSrc2 = oatGetSrcWide(cUnit, mir, 2, 3);
+ rlSrc1 = oatGetSrcWide(cUnit, mir, 0);
+ rlSrc2 = oatGetSrcWide(cUnit, mir, 2);
rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg);
rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
newLIR2(cUnit, kThumb2Vcmpd, S2D(rlSrc1.lowReg, r1Src2.highReg),
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 9ec470c168..579aa435a6 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -182,7 +182,7 @@ MIR* specialIPut(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir,
RegLocation rlObj;
lockLiveArgs(cUnit, mir);
if (longOrDouble) {
- rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+ rlSrc = oatGetSrcWide(cUnit, mir, 0);
rlObj = oatGetSrc(cUnit, mir, 2);
} else {
rlSrc = oatGetSrc(cUnit, mir, 0);
@@ -210,7 +210,7 @@ MIR* specialIdentity(CompilationUnit* cUnit, MIR* mir)
RegLocation rlDest;
bool wide = (mir->ssaRep->numUses == 2);
if (wide) {
- rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+ rlSrc = oatGetSrcWide(cUnit, mir, 0);
rlDest = oatGetReturnWide(cUnit, false);
} else {
rlSrc = oatGetSrc(cUnit, mir, 0);
@@ -657,8 +657,8 @@ void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
LIR* labelList = (LIR*)cUnit->blockLabelList;
LIR* taken = &labelList[bb->taken->id];
LIR* notTaken = &labelList[bb->fallThrough->id];
- RegLocation rlSrc1 = oatGetSrcWide(cUnit, mir, 0, 1);
- RegLocation rlSrc2 = oatGetSrcWide(cUnit, mir, 2, 3);
+ RegLocation rlSrc1 = oatGetSrcWide(cUnit, mir, 0);
+ RegLocation rlSrc2 = oatGetSrcWide(cUnit, mir, 2);
rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]);