summaryrefslogtreecommitdiff
path: root/src/compiler/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/codegen')
-rw-r--r--src/compiler/codegen/CodegenFactory.cc40
-rw-r--r--src/compiler/codegen/GenCommon.cc34
-rw-r--r--src/compiler/codegen/MethodCodegenDriver.cc18
-rw-r--r--src/compiler/codegen/Ralloc.h6
-rw-r--r--src/compiler/codegen/RallocUtil.cc48
-rw-r--r--src/compiler/codegen/arm/ArchFactory.cc16
-rw-r--r--src/compiler/codegen/arm/ArmRallocUtil.cc8
-rw-r--r--src/compiler/codegen/arm/Thumb2/Ralloc.cc4
-rw-r--r--src/compiler/codegen/mips/MipsRallocUtil.cc8
-rw-r--r--src/compiler/codegen/x86/X86RallocUtil.cc8
10 files changed, 117 insertions, 73 deletions
diff --git a/src/compiler/codegen/CodegenFactory.cc b/src/compiler/codegen/CodegenFactory.cc
index 8a6e1bc967..5444816ddf 100644
--- a/src/compiler/codegen/CodegenFactory.cc
+++ b/src/compiler/codegen/CodegenFactory.cc
@@ -65,7 +65,8 @@ void loadValueDirect(CompilationUnit* cUnit, RegLocation rlSrc, int reg1)
if (rlSrc.location == kLocPhysReg) {
opRegCopy(cUnit, reg1, rlSrc.lowReg);
} else {
- DCHECK(rlSrc.location == kLocDalvikFrame);
+ DCHECK((rlSrc.location == kLocDalvikFrame) ||
+ (rlSrc.location == kLocCompilerTemp));
loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, rlSrc.sRegLow), reg1);
}
}
@@ -94,7 +95,8 @@ void loadValueDirectWide(CompilationUnit* cUnit, RegLocation rlSrc, int regLo,
if (rlSrc.location == kLocPhysReg) {
opRegCopyWide(cUnit, regLo, regHi, rlSrc.lowReg, rlSrc.highReg);
} else {
- DCHECK(rlSrc.location == kLocDalvikFrame);
+ DCHECK((rlSrc.location == kLocDalvikFrame) ||
+ (rlSrc.location == kLocCompilerTemp));
loadBaseDispWide(cUnit, NULL, rSP,
oatSRegOffset(cUnit, rlSrc.sRegLow),
regLo, regHi, INVALID_SREG);
@@ -120,7 +122,9 @@ RegLocation loadValue(CompilationUnit* cUnit, RegLocation rlSrc,
RegisterClass opKind)
{
rlSrc = oatEvalLoc(cUnit, rlSrc, opKind, false);
- if (rlSrc.location == kLocDalvikFrame) {
+ if (rlSrc.location != kLocPhysReg) {
+ DCHECK((rlSrc.location == kLocDalvikFrame) ||
+ (rlSrc.location == kLocCompilerTemp));
loadValueDirect(cUnit, rlSrc, rlSrc.lowReg);
rlSrc.location = kLocPhysReg;
oatMarkLive(cUnit, rlSrc.lowReg, rlSrc.sRegLow);
@@ -176,7 +180,9 @@ RegLocation loadValueWide(CompilationUnit* cUnit, RegLocation rlSrc,
{
DCHECK(rlSrc.wide);
rlSrc = oatEvalLoc(cUnit, rlSrc, opKind, false);
- if (rlSrc.location == kLocDalvikFrame) {
+ if (rlSrc.location != kLocPhysReg) {
+ DCHECK((rlSrc.location == kLocDalvikFrame) ||
+ (rlSrc.location == kLocCompilerTemp));
loadValueDirectWide(cUnit, rlSrc, rlSrc.lowReg, rlSrc.highReg);
rlSrc.location = kLocPhysReg;
oatMarkLive(cUnit, rlSrc.lowReg, rlSrc.sRegLow);
@@ -232,8 +238,8 @@ void storeValueWide(CompilationUnit* cUnit, RegLocation rlDest,
(oatLiveOut(cUnit, rlDest.sRegLow) ||
oatLiveOut(cUnit, oatSRegHi(rlDest.sRegLow)))) {
defStart = (LIR*)cUnit->lastLIRInsn;
- DCHECK_EQ((oatS2VReg(cUnit, rlDest.sRegLow)+1),
- oatS2VReg(cUnit, oatSRegHi(rlDest.sRegLow)));
+ DCHECK_EQ((SRegToVReg(cUnit, rlDest.sRegLow)+1),
+ SRegToVReg(cUnit, oatSRegHi(rlDest.sRegLow)));
storeBaseDispWide(cUnit, rSP, oatSRegOffset(cUnit, rlDest.sRegLow),
rlDest.lowReg, rlDest.highReg);
oatMarkClean(cUnit, rlDest);
@@ -265,29 +271,15 @@ void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg)
#endif
}
-/*
- * Utility to load the current Method*. Broken out
- * to allow easy change between placing the current Method* in a
- * dedicated register or its home location in the frame.
- */
+/* Utilities to load the current Method* */
void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt)
{
-#if defined(METHOD_IN_REG)
- opRegCopy(cUnit, rTgt, rMETHOD);
-#else
- loadWordDisp(cUnit, rSP, 0, rTgt);
-#endif
+ loadValueDirectFixed(cUnit, cUnit->regLocation[cUnit->methodSReg], rTgt);
}
-int loadCurrMethod(CompilationUnit *cUnit)
+RegLocation loadCurrMethod(CompilationUnit *cUnit)
{
-#if defined(METHOD_IN_REG)
- return rMETHOD;
-#else
- int mReg = oatAllocTemp(cUnit);
- loadCurrMethodDirect(cUnit, mReg);
- return mReg;
-#endif
+ return loadValue(cUnit, cUnit->regLocation[cUnit->methodSReg], kCoreReg);
}
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index e2c306de37..9b1654f764 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -275,10 +275,12 @@ void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange)
rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
pCheckAndAllocArrayFromCodeWithAccessCheck));
}
- loadCurrMethodDirect(cUnit, rARG1); // arg1 <- Method*
loadConstant(cUnit, rARG0, typeId); // arg0 <- type_id
loadConstant(cUnit, rARG2, elems); // arg2 <- count
+ loadCurrMethodDirect(cUnit, rARG1); // arg1 <- Method*
callRuntimeHelper(cUnit, rTgt);
+ oatFreeTemp(cUnit, rARG2);
+ oatFreeTemp(cUnit, rARG1);
/*
* NOTE: the implicit target for Instruction::FILLED_NEW_ARRAY is the
* return region. Because AllocFromCode placed the new array
@@ -387,12 +389,11 @@ void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
if (fastPath && !SLOW_FIELD_PATH) {
DCHECK_GE(fieldOffset, 0);
int rBase;
- int rMethod;
if (isReferrersClass) {
// Fast path, static storage base is this method's class
- rMethod = loadCurrMethod(cUnit);
+ RegLocation rlMethod = loadCurrMethod(cUnit);
rBase = oatAllocTemp(cUnit);
- loadWordDisp(cUnit, rMethod,
+ loadWordDisp(cUnit, rlMethod.lowReg,
Method::DeclaringClassOffset().Int32Value(), rBase);
} else {
// Medium path, static storage base in a different class which
@@ -402,7 +403,7 @@ void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
oatFlushAllRegs(cUnit);
// Using fixed register to sync with possible call to runtime
// support.
- rMethod = rARG1;
+ int rMethod = rARG1;
oatLockTemp(cUnit, rMethod);
loadCurrMethodDirect(cUnit, rMethod);
rBase = rARG0;
@@ -427,9 +428,9 @@ void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
#endif
LIR* skipTarget = newLIR0(cUnit, kPseudoTargetLabel);
branchOver->target = (LIR*)skipTarget;
+ oatFreeTemp(cUnit, rMethod);
}
// rBase now holds static storage base
- oatFreeTemp(cUnit, rMethod);
if (isLongOrDouble) {
rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
@@ -496,12 +497,11 @@ void genSget(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
if (fastPath && !SLOW_FIELD_PATH) {
DCHECK_GE(fieldOffset, 0);
int rBase;
- int rMethod;
if (isReferrersClass) {
// Fast path, static storage base is this method's class
- rMethod = loadCurrMethod(cUnit);
+ RegLocation rlMethod = loadCurrMethod(cUnit);
rBase = oatAllocTemp(cUnit);
- loadWordDisp(cUnit, rMethod,
+ loadWordDisp(cUnit, rlMethod.lowReg,
Method::DeclaringClassOffset().Int32Value(), rBase);
} else {
// Medium path, static storage base in a different class which
@@ -511,7 +511,7 @@ void genSget(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
oatFlushAllRegs(cUnit);
// Using fixed register to sync with possible call to runtime
// support
- rMethod = rARG1;
+ int rMethod = rARG1;
oatLockTemp(cUnit, rMethod);
loadCurrMethodDirect(cUnit, rMethod);
rBase = rARG0;
@@ -537,9 +537,9 @@ void genSget(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
#endif
LIR* skipTarget = newLIR0(cUnit, kPseudoTargetLabel);
branchOver->target = (LIR*)skipTarget;
+ oatFreeTemp(cUnit, rMethod);
}
// rBase now holds static storage base
- oatFreeTemp(cUnit, rMethod);
rlDest = isLongOrDouble ? oatGetDestWide(cUnit, mir, 0, 1)
: oatGetDest(cUnit, mir, 0);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
@@ -837,7 +837,7 @@ void genConstClass(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
RegLocation rlSrc)
{
uint32_t type_idx = mir->dalvikInsn.vB;
- int mReg = loadCurrMethod(cUnit);
+ RegLocation rlMethod = loadCurrMethod(cUnit);
int resReg = oatAllocTemp(cUnit);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
@@ -848,7 +848,7 @@ void genConstClass(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
// Resolved type returned in rRET0.
int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
pInitializeTypeAndVerifyAccessFromCode));
- opRegCopy(cUnit, rARG1, mReg);
+ opRegCopy(cUnit, rARG1, rlMethod.lowReg);
loadConstant(cUnit, rARG0, type_idx);
callRuntimeHelper(cUnit, rTgt);
RegLocation rlResult = oatGetReturn(cUnit);
@@ -857,7 +857,7 @@ void genConstClass(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
// We're don't need access checks, load type from dex cache
int32_t dex_cache_offset =
Method::DexCacheResolvedTypesOffset().Int32Value();
- loadWordDisp(cUnit, mReg, dex_cache_offset, resReg);
+ loadWordDisp(cUnit, rlMethod.lowReg, dex_cache_offset, resReg);
int32_t offset_of_type =
Array::DataOffset(sizeof(Class*)).Int32Value() + (sizeof(Class*)
* type_idx);
@@ -876,7 +876,7 @@ void genConstClass(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
// Call out to helper, which will return resolved type in rARG0
int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
pInitializeTypeFromCode));
- opRegCopy(cUnit, rARG1, mReg);
+ opRegCopy(cUnit, rARG1, rlMethod.lowReg);
loadConstant(cUnit, rARG0, type_idx);
callRuntimeHelper(cUnit, rTgt);
RegLocation rlResult = oatGetReturn(cUnit);
@@ -930,10 +930,10 @@ void genConstString(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
genBarrier(cUnit);
storeValue(cUnit, rlDest, oatGetReturn(cUnit));
} else {
- int mReg = loadCurrMethod(cUnit);
+ RegLocation rlMethod = loadCurrMethod(cUnit);
int resReg = oatAllocTemp(cUnit);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
- loadWordDisp(cUnit, mReg,
+ loadWordDisp(cUnit, rlMethod.lowReg,
Method::DexCacheStringsOffset().Int32Value(), resReg);
loadWordDisp(cUnit, resReg, offset_of_string, rlResult.lowReg);
storeValue(cUnit, rlDest, rlResult);
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index 6b3283e13f..5baabf2f32 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -716,8 +716,7 @@ const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
"kMirOpNullNRangeUpCheck",
"kMirOpNullNRangeDownCheck",
"kMirOpLowerBound",
- "kMirOpPunt",
- "kMirOpCheckInlinePrediction",
+ "kMirOpCopy",
};
/* Extended MIR instructions like PHI */
@@ -742,6 +741,9 @@ void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
break;
}
+ case kMirOpCopy:
+ UNIMPLEMENTED(FATAL) << "Need kMirOpCopy";
+ break;
default:
break;
}
@@ -761,11 +763,19 @@ bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
labelList[blockId].opcode = kPseudoNormalBlockLabel;
oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
- /* Reset local optimization data on block boundaries */
+ /* Free temp registers and reset redundant store tracking */
oatResetRegPool(cUnit);
- oatClobberAllRegs(cUnit);
oatResetDefTracking(cUnit);
+ /*
+ * If control reached us from our immediate predecessor via
+ * fallthrough and we have no other incoming arcs we can
+ * reuse existing liveness. Otherwise, reset.
+ */
+ if (!bb->fallThroughTarget || bb->predecessors->numUsed != 1) {
+ oatClobberAllRegs(cUnit);
+ }
+
LIR* headLIR = NULL;
if (bb->blockType == kEntryBlock) {
diff --git a/src/compiler/codegen/Ralloc.h b/src/compiler/codegen/Ralloc.h
index 8c8c693edb..d32545c248 100644
--- a/src/compiler/codegen/Ralloc.h
+++ b/src/compiler/codegen/Ralloc.h
@@ -35,12 +35,6 @@ struct RefCounts {
};
-inline int oatS2VReg(CompilationUnit* cUnit, int sReg)
-{
- DCHECK_NE(sReg, INVALID_SREG);
- return DECODE_REG(oatConvertSSARegToDalvik(cUnit, sReg));
-}
-
/*
* Get the "real" sreg number associated with an sReg slot. In general,
* sReg values passed through codegen are the SSA names created by
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc
index b5ebf65da0..8f5d1bbe5a 100644
--- a/src/compiler/codegen/RallocUtil.cc
+++ b/src/compiler/codegen/RallocUtil.cc
@@ -147,6 +147,19 @@ extern void oatClobberSReg(CompilationUnit* cUnit, int sReg)
sReg);
}
+/* Sanity check */
+bool validSreg(CompilationUnit* cUnit, int sReg)
+{
+ bool res = ((-(cUnit->numCompilerTemps + 1) <= sReg) &&
+ (sReg < cUnit->numDalvikRegisters));
+ if (!res) {
+ LOG(WARNING) << "Bad sreg: " << sReg;
+ LOG(WARNING) << " low = " << -(cUnit->numCompilerTemps + 1);
+ LOG(WARNING) << " high = " << cUnit->numRegs;
+ }
+ return res;
+}
+
/* Reserve a callee-save register. Return -1 if none available */
extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sReg)
{
@@ -160,7 +173,8 @@ extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sReg)
cUnit->coreVmapTable.push_back(sReg);
cUnit->numCoreSpills++;
// Should be promoting based on initial sReg set
- DCHECK_EQ(sReg, oatS2VReg(cUnit, sReg));
+ DCHECK_EQ(sReg, SRegToVReg(cUnit, sReg));
+ DCHECK(validSreg(cUnit,sReg));
cUnit->promotionMap[sReg].coreLocation = kLocPhysReg;
cUnit->promotionMap[sReg].coreReg = res;
break;
@@ -184,8 +198,9 @@ int allocPreservedSingle(CompilationUnit* cUnit, int sReg, bool even)
res = FPRegs[i].reg;
FPRegs[i].inUse = true;
// Should be promoting based on initial sReg set
- DCHECK_EQ(sReg, oatS2VReg(cUnit, sReg));
+ DCHECK_EQ(sReg, SRegToVReg(cUnit, sReg));
oatMarkPreservedSingle(cUnit, sReg, res);
+ DCHECK(validSreg(cUnit,sReg));
cUnit->promotionMap[sReg].fpLocation = kLocPhysReg;
cUnit->promotionMap[sReg].fpReg = res;
break;
@@ -206,7 +221,8 @@ int allocPreservedDouble(CompilationUnit* cUnit, int sReg)
{
int res = -1; // Assume failure
// Should be promoting based on initial sReg set
- DCHECK_EQ(sReg, oatS2VReg(cUnit, sReg));
+ DCHECK_EQ(sReg, SRegToVReg(cUnit, sReg));
+ DCHECK(validSreg(cUnit,sReg+1));
if (cUnit->promotionMap[sReg+1].fpLocation == kLocPhysReg) {
// Upper reg is already allocated. Can we fit?
int highReg = cUnit->promotionMap[sReg+1].fpReg;
@@ -244,8 +260,10 @@ int allocPreservedDouble(CompilationUnit* cUnit, int sReg)
}
}
if (res != -1) {
+ DCHECK(validSreg(cUnit,sReg));
cUnit->promotionMap[sReg].fpLocation = kLocPhysReg;
cUnit->promotionMap[sReg].fpReg = res;
+ DCHECK(validSreg(cUnit,sReg+1));
cUnit->promotionMap[sReg+1].fpLocation = kLocPhysReg;
cUnit->promotionMap[sReg+1].fpReg = res + 1;
}
@@ -788,7 +806,9 @@ extern RegLocation oatUpdateLoc(CompilationUnit* cUnit, RegLocation loc)
{
DCHECK(!loc.wide);
DCHECK(oatCheckCorePoolSanity(cUnit));
- if (loc.location == kLocDalvikFrame) {
+ if (loc.location != kLocPhysReg) {
+ DCHECK((loc.location == kLocDalvikFrame) ||
+ (loc.location == kLocCompilerTemp));
RegisterInfo* infoLo = allocLive(cUnit, loc.sRegLow, kAnyReg);
if (infoLo) {
if (infoLo->pair) {
@@ -837,7 +857,9 @@ extern RegLocation oatUpdateLocWide(CompilationUnit* cUnit, RegLocation loc)
{
DCHECK(loc.wide);
DCHECK(oatCheckCorePoolSanity(cUnit));
- if (loc.location == kLocDalvikFrame) {
+ if (loc.location != kLocPhysReg) {
+ DCHECK((loc.location == kLocDalvikFrame) ||
+ (loc.location == kLocCompilerTemp));
// Are the dalvik regs already live in physical registers?
RegisterInfo* infoLo = allocLive(cUnit, loc.sRegLow, kAnyReg);
RegisterInfo* infoHi = allocLive(cUnit,
@@ -1026,7 +1048,7 @@ void oatCountRefs(CompilationUnit *cUnit, BasicBlock* bb,
for (int i = 0; i < ssaRep->numDefs;) {
RegLocation loc = cUnit->regLocation[ssaRep->defs[i]];
RefCounts* counts = loc.fp ? fpCounts : coreCounts;
- int vReg = oatS2VReg(cUnit, ssaRep->defs[i]);
+ int vReg = SRegToVReg(cUnit, ssaRep->defs[i]);
if (loc.defined) {
counts[vReg].count++;
}
@@ -1045,7 +1067,7 @@ void oatCountRefs(CompilationUnit *cUnit, BasicBlock* bb,
for (int i = 0; i < ssaRep->numUses;) {
RegLocation loc = cUnit->regLocation[ssaRep->uses[i]];
RefCounts* counts = loc.fp ? fpCounts : coreCounts;
- int vReg = oatS2VReg(cUnit, ssaRep->uses[i]);
+ int vReg = SRegToVReg(cUnit, ssaRep->uses[i]);
if (loc.defined) {
counts[vReg].count++;
}
@@ -1142,6 +1164,7 @@ extern void oatDoPromotion(CompilationUnit* cUnit)
if (!(cUnit->disableOpt & (1 << kPromoteRegs))) {
// Promote fpRegs
for (int i = 0; (fpRegs[i].count > 0) && (i < numRegs); i++) {
+ DCHECK(validSreg(cUnit,fpRegs[i].sReg));
if (cUnit->promotionMap[fpRegs[i].sReg].fpLocation != kLocPhysReg) {
int reg = oatAllocPreservedFPReg(cUnit, fpRegs[i].sReg,
fpRegs[i].doubleStart);
@@ -1153,6 +1176,7 @@ extern void oatDoPromotion(CompilationUnit* cUnit)
// Promote core regs
for (int i = 0; (coreRegs[i].count > 0) && i < numRegs; i++) {
+ DCHECK(validSreg(cUnit,coreRegs[i].sReg));
if (cUnit->promotionMap[coreRegs[i].sReg].coreLocation !=
kLocPhysReg) {
int reg = oatAllocPreservedCoreReg(cUnit, coreRegs[i].sReg);
@@ -1166,15 +1190,17 @@ extern void oatDoPromotion(CompilationUnit* cUnit)
// Now, update SSA names to new home locations
for (int i = 0; i < cUnit->numSSARegs; i++) {
RegLocation *curr = &cUnit->regLocation[i];
- int baseVReg = oatS2VReg(cUnit, curr->sRegLow);
+ int baseVReg = SRegToVReg(cUnit, curr->sRegLow);
if (!curr->wide) {
if (curr->fp) {
+ DCHECK(validSreg(cUnit,baseVReg));
if (cUnit->promotionMap[baseVReg].fpLocation == kLocPhysReg) {
curr->location = kLocPhysReg;
curr->lowReg = cUnit->promotionMap[baseVReg].fpReg;
curr->home = true;
}
} else {
+ DCHECK(validSreg(cUnit,baseVReg));
if (cUnit->promotionMap[baseVReg].coreLocation == kLocPhysReg) {
curr->location = kLocPhysReg;
curr->lowReg = cUnit->promotionMap[baseVReg].coreReg;
@@ -1187,6 +1213,8 @@ extern void oatDoPromotion(CompilationUnit* cUnit)
continue;
}
if (curr->fp) {
+ DCHECK(validSreg(cUnit,baseVReg));
+ DCHECK(validSreg(cUnit,baseVReg+1));
if ((cUnit->promotionMap[baseVReg].fpLocation == kLocPhysReg) &&
(cUnit->promotionMap[baseVReg+1].fpLocation ==
kLocPhysReg)) {
@@ -1201,6 +1229,8 @@ extern void oatDoPromotion(CompilationUnit* cUnit)
}
}
} else {
+ DCHECK(validSreg(cUnit,baseVReg));
+ DCHECK(validSreg(cUnit,baseVReg+1));
if ((cUnit->promotionMap[baseVReg].coreLocation == kLocPhysReg)
&& (cUnit->promotionMap[baseVReg+1].coreLocation ==
kLocPhysReg)) {
@@ -1224,7 +1254,7 @@ extern int oatVRegOffset(CompilationUnit* cUnit, int vReg)
/* Returns sp-relative offset in bytes for a SReg */
extern int oatSRegOffset(CompilationUnit* cUnit, int sReg)
{
- return oatVRegOffset(cUnit, oatS2VReg(cUnit, sReg));
+ return oatVRegOffset(cUnit, SRegToVReg(cUnit, sReg));
}
} // namespace art
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index 8a23d5c2e1..da5de521f3 100644
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ b/src/compiler/codegen/arm/ArchFactory.cc
@@ -106,7 +106,21 @@ void genEntrySequence(CompilationUnit* cUnit, BasicBlock* bb)
opRegImm(cUnit, kOpSub, rSP,
cUnit->frameSize - (spillCount * 4));
}
- storeBaseDisp(cUnit, rSP, 0, r0, kWord);
+
+ /*
+ * Dummy up a RegLocation for the incoming Method*
+ * It will attempt to keep r0 live (or copy it to home location
+ * if promoted).
+ */
+ RegLocation rlSrc = cUnit->regLocation[cUnit->methodSReg];
+ RegLocation rlMethod = cUnit->regLocation[cUnit->methodSReg];
+ rlSrc.location = kLocPhysReg;
+ rlSrc.lowReg = r0;
+ rlSrc.home = false;
+ oatMarkLive(cUnit, rlSrc.lowReg, rlSrc.sRegLow);
+ storeValue(cUnit, rlMethod, rlSrc);
+
+ /* Flush the rest of the ins */
flushIns(cUnit);
if (cUnit->genDebugger) {
diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc
index 3335f5997e..e7627f2367 100644
--- a/src/compiler/codegen/arm/ArmRallocUtil.cc
+++ b/src/compiler/codegen/arm/ArmRallocUtil.cc
@@ -76,10 +76,10 @@ void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
info1->dirty = false;
info2->dirty = false;
- if (oatS2VReg(cUnit, info2->sReg) <
- oatS2VReg(cUnit, info1->sReg))
+ if (SRegToVReg(cUnit, info2->sReg) <
+ SRegToVReg(cUnit, info1->sReg))
info1 = info2;
- int vReg = oatS2VReg(cUnit, info1->sReg);
+ int vReg = SRegToVReg(cUnit, info1->sReg);
oatFlushRegWideImpl(cUnit, rSP,
oatVRegOffset(cUnit, vReg),
info1->reg, info1->partner);
@@ -91,7 +91,7 @@ void oatFlushReg(CompilationUnit* cUnit, int reg)
RegisterInfo* info = oatGetRegInfo(cUnit, reg);
if (info->live && info->dirty) {
info->dirty = false;
- int vReg = oatS2VReg(cUnit, info->sReg);
+ int vReg = SRegToVReg(cUnit, info->sReg);
oatFlushRegImpl(cUnit, rSP,
oatVRegOffset(cUnit, vReg),
reg, kWord);
diff --git a/src/compiler/codegen/arm/Thumb2/Ralloc.cc b/src/compiler/codegen/arm/Thumb2/Ralloc.cc
index c0f2c771ca..7858318001 100644
--- a/src/compiler/codegen/arm/Thumb2/Ralloc.cc
+++ b/src/compiler/codegen/arm/Thumb2/Ralloc.cc
@@ -88,6 +88,10 @@ void oatInitializeRegAlloc(CompilationUnit* cUnit)
for (int i = 0; i < numFPTemps; i++) {
oatMarkTemp(cUnit, fpTemps[i]);
}
+
+ // Start allocation at r2 in an attempt to avoid clobbering return values
+ pool->nextCoreReg = r2;
+
// Construct the alias map.
cUnit->phiAliasMap = (int*)oatNew(cUnit, cUnit->numSSARegs *
sizeof(cUnit->phiAliasMap[0]), false,
diff --git a/src/compiler/codegen/mips/MipsRallocUtil.cc b/src/compiler/codegen/mips/MipsRallocUtil.cc
index 7fd9b598cd..7ed3f86c3e 100644
--- a/src/compiler/codegen/mips/MipsRallocUtil.cc
+++ b/src/compiler/codegen/mips/MipsRallocUtil.cc
@@ -65,10 +65,10 @@ void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
info1->dirty = false;
info2->dirty = false;
- if (oatS2VReg(cUnit, info2->sReg) <
- oatS2VReg(cUnit, info1->sReg))
+ if (SRegToVReg(cUnit, info2->sReg) <
+ SRegToVReg(cUnit, info1->sReg))
info1 = info2;
- int vReg = oatS2VReg(cUnit, info1->sReg);
+ int vReg = SRegToVReg(cUnit, info1->sReg);
oatFlushRegWideImpl(cUnit, rSP,
oatVRegOffset(cUnit, vReg),
info1->reg, info1->partner);
@@ -80,7 +80,7 @@ void oatFlushReg(CompilationUnit* cUnit, int reg)
RegisterInfo* info = oatGetRegInfo(cUnit, reg);
if (info->live && info->dirty) {
info->dirty = false;
- int vReg = oatS2VReg(cUnit, info->sReg);
+ int vReg = SRegToVReg(cUnit, info->sReg);
oatFlushRegImpl(cUnit, rSP,
oatVRegOffset(cUnit, vReg),
reg, kWord);
diff --git a/src/compiler/codegen/x86/X86RallocUtil.cc b/src/compiler/codegen/x86/X86RallocUtil.cc
index 7c99fd6298..1b4eca4158 100644
--- a/src/compiler/codegen/x86/X86RallocUtil.cc
+++ b/src/compiler/codegen/x86/X86RallocUtil.cc
@@ -60,10 +60,10 @@ void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
info1->dirty = false;
info2->dirty = false;
- if (oatS2VReg(cUnit, info2->sReg) <
- oatS2VReg(cUnit, info1->sReg))
+ if (SRegToVReg(cUnit, info2->sReg) <
+ SRegToVReg(cUnit, info1->sReg))
info1 = info2;
- int vReg = oatS2VReg(cUnit, info1->sReg);
+ int vReg = SRegToVReg(cUnit, info1->sReg);
oatFlushRegWideImpl(cUnit, rSP,
oatVRegOffset(cUnit, vReg),
info1->reg, info1->partner);
@@ -75,7 +75,7 @@ void oatFlushReg(CompilationUnit* cUnit, int reg)
RegisterInfo* info = oatGetRegInfo(cUnit, reg);
if (info->live && info->dirty) {
info->dirty = false;
- int vReg = oatS2VReg(cUnit, info->sReg);
+ int vReg = SRegToVReg(cUnit, info->sReg);
oatFlushRegImpl(cUnit, rSP,
oatVRegOffset(cUnit, vReg),
reg, kWord);