From e196567b50a084b163937ea9605b51ee1e48adeb Mon Sep 17 00:00:00 2001 From: buzbee Date: Sun, 11 Mar 2012 18:39:19 -0700 Subject: SSA rework and support compiler temps in the frame Add ability for the compiler to allocate new frame temporaries that play nicely with the register allocation mechanism. To do this we assign negative virtual register numbers and give them SSA names. As part of this change, I did a general cleanup of the ssa naming. An ssa name (or SReg) is in index into an array of (virtual reg, subscript) pairs. Previously, 16 bits were allocated for the reg and the subscript. This CL expands the virtual reg and subscript to 32 bits each. Method* is now treated as a RegLocation, and will be subject to temp register tracking and reuse. This CL does not yet include support for promotion of Method* - that will show up in the next one. Also included is the beginning of a basic block optimization pass (not yet in a runable state, so conditionally compiled out). (cherry picked from commit f689ffec8827f1dd6b31084f8a6bb240338c7acf) Change-Id: Ibbdeb97fe05d0e33c1f4a9a6ccbdef1cac7646fc --- src/compiler/codegen/CodegenFactory.cc | 40 ++++++++++-------------- src/compiler/codegen/GenCommon.cc | 34 ++++++++++---------- src/compiler/codegen/MethodCodegenDriver.cc | 18 ++++++++--- src/compiler/codegen/Ralloc.h | 6 ---- src/compiler/codegen/RallocUtil.cc | 48 +++++++++++++++++++++++------ src/compiler/codegen/arm/ArchFactory.cc | 16 +++++++++- src/compiler/codegen/arm/ArmRallocUtil.cc | 8 ++--- src/compiler/codegen/arm/Thumb2/Ralloc.cc | 4 +++ src/compiler/codegen/mips/MipsRallocUtil.cc | 8 ++--- src/compiler/codegen/x86/X86RallocUtil.cc | 8 ++--- 10 files changed, 117 insertions(+), 73 deletions(-) (limited to 'src/compiler/codegen') 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); -- cgit v1.2.3-59-g8ed1b