diff options
Diffstat (limited to 'src/compiler/codegen')
| -rw-r--r-- | src/compiler/codegen/CodegenFactory.cc | 14 | ||||
| -rw-r--r-- | src/compiler/codegen/CompilerCodegen.h | 2 | ||||
| -rw-r--r-- | src/compiler/codegen/Ralloc.h | 1 | ||||
| -rw-r--r-- | src/compiler/codegen/RallocUtil.cc | 31 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArchUtility.cc | 50 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArmLIR.h | 15 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArmRallocUtil.cc | 185 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/MethodCodegenDriver.cc | 107 |
8 files changed, 203 insertions, 202 deletions
diff --git a/src/compiler/codegen/CodegenFactory.cc b/src/compiler/codegen/CodegenFactory.cc index 55ed8af080..5dbcd9769a 100644 --- a/src/compiler/codegen/CodegenFactory.cc +++ b/src/compiler/codegen/CodegenFactory.cc @@ -58,7 +58,7 @@ STATIC void loadValueDirect(CompilationUnit* cUnit, RegLocation rlSrc, genRegCopy(cUnit, reg1, rlSrc.lowReg); } else { DCHECK(rlSrc.location == kLocDalvikFrame); - loadWordDisp(cUnit, rSP, rlSrc.spOffset, reg1); + loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, rlSrc.sRegLow), reg1); } } @@ -88,7 +88,8 @@ STATIC void loadValueDirectWide(CompilationUnit* cUnit, RegLocation rlSrc, genRegCopyWide(cUnit, regLo, regHi, rlSrc.lowReg, rlSrc.highReg); } else { DCHECK(rlSrc.location == kLocDalvikFrame); - loadBaseDispWide(cUnit, NULL, rSP, rlSrc.spOffset, + loadBaseDispWide(cUnit, NULL, rSP, + oatSRegOffset(cUnit, rlSrc.sRegLow), regLo, regHi, INVALID_SREG); } } @@ -156,7 +157,8 @@ STATIC void storeValue(CompilationUnit* cUnit, RegLocation rlDest, if (oatIsDirty(cUnit, rlDest.lowReg) && oatLiveOut(cUnit, rlDest.sRegLow)) { defStart = (LIR* )cUnit->lastLIRInsn; - storeBaseDisp(cUnit, rSP, rlDest.spOffset, rlDest.lowReg, kWord); + storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, rlDest.sRegLow), + rlDest.lowReg, kWord); oatMarkClean(cUnit, rlDest); defEnd = (LIR* )cUnit->lastLIRInsn; oatMarkDef(cUnit, rlDest, defStart, defEnd); @@ -183,10 +185,6 @@ STATIC void storeValueWide(CompilationUnit* cUnit, RegLocation rlDest, { LIR* defStart; LIR* defEnd; - if (FPREG(rlSrc.lowReg)!=FPREG(rlSrc.highReg)) { - LOG(WARNING) << "rlSrc.lowreg:" << rlSrc.lowReg << ", rlSrc.highReg:" - << rlSrc.highReg; - } DCHECK_EQ(FPREG(rlSrc.lowReg), FPREG(rlSrc.highReg)); DCHECK(rlDest.wide); DCHECK(rlSrc.wide); @@ -230,7 +228,7 @@ STATIC void storeValueWide(CompilationUnit* cUnit, RegLocation rlDest, defStart = (LIR*)cUnit->lastLIRInsn; DCHECK_EQ((oatS2VReg(cUnit, rlDest.sRegLow)+1), oatS2VReg(cUnit, oatSRegHi(rlDest.sRegLow))); - storeBaseDispWide(cUnit, rSP, rlDest.spOffset, + storeBaseDispWide(cUnit, rSP, oatSRegOffset(cUnit, rlDest.sRegLow), rlDest.lowReg, rlDest.highReg); oatMarkClean(cUnit, rlDest); defEnd = (LIR*)cUnit->lastLIRInsn; diff --git a/src/compiler/codegen/CompilerCodegen.h b/src/compiler/codegen/CompilerCodegen.h index 58ab1d3b97..d2e5f0a631 100644 --- a/src/compiler/codegen/CompilerCodegen.h +++ b/src/compiler/codegen/CompilerCodegen.h @@ -27,6 +27,8 @@ void oatAssembleLIR(CompilationUnit* cUnit); /* Implemented in the codegen/<target>/ArchUtility.c */ void oatCodegenDump(CompilationUnit* cUnit); +void oatDumpPromotionMap(CompilationUnit* cUnit); +void oatDumpFullPromotionMap(CompilationUnit* cUnit); /* Implemented in codegen/<target>/Ralloc.c */ void oatSimpleRegAlloc(CompilationUnit* cUnit); diff --git a/src/compiler/codegen/Ralloc.h b/src/compiler/codegen/Ralloc.h index e343ec5682..fee0e9a913 100644 --- a/src/compiler/codegen/Ralloc.h +++ b/src/compiler/codegen/Ralloc.h @@ -232,6 +232,7 @@ extern void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase, extern void oatDoPromotion(CompilationUnit* cUnit); extern int oatVRegOffset(CompilationUnit* cUnit, int reg); +extern int oatSRegOffset(CompilationUnit* cUnit, int reg); extern void oatDumpCoreRegPool(CompilationUnit* cUint); extern void oatDumpFPRegPool(CompilationUnit* cUint); extern bool oatCheckCorePoolSanity(CompilationUnit* cUnit); diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc index 7fd062d5a5..1b0fb90e35 100644 --- a/src/compiler/codegen/RallocUtil.cc +++ b/src/compiler/codegen/RallocUtil.cc @@ -186,9 +186,10 @@ extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sReg) cUnit->coreSpillMask |= (1 << res); cUnit->coreVmapTable.push_back(sReg); cUnit->numCoreSpills++; - cUnit->regLocation[sReg].location = kLocPhysReg; - cUnit->regLocation[sReg].lowReg = res; - cUnit->regLocation[sReg].home = true; + // Should be promoting based on initial sReg set + DCHECK_EQ(sReg, oatS2VReg(cUnit, sReg)); + cUnit->promotionMap[sReg].coreLocation = kLocPhysReg; + cUnit->promotionMap[sReg].coreReg = res; break; } } @@ -231,10 +232,11 @@ STATIC int allocPreservedSingle(CompilationUnit* cUnit, int sReg, bool even) ((FPRegs[i].reg & 0x1) == 0) == even) { res = FPRegs[i].reg; FPRegs[i].inUse = true; + // Should be promoting based on initial sReg set + DCHECK_EQ(sReg, oatS2VReg(cUnit, sReg)); markPreservedSingle(cUnit, sReg, res); - cUnit->regLocation[sReg].fpLocation = kLocPhysReg; - cUnit->regLocation[sReg].fpLowReg = res; - cUnit->regLocation[sReg].home = true; + cUnit->promotionMap[sReg].fpLocation = kLocPhysReg; + cUnit->promotionMap[sReg].fpReg = res; break; } } @@ -252,9 +254,11 @@ STATIC int allocPreservedSingle(CompilationUnit* cUnit, int sReg, bool even) STATIC int allocPreservedDouble(CompilationUnit* cUnit, int sReg) { int res = -1; // Assume failure - if (cUnit->regLocation[sReg+1].fpLocation == kLocPhysReg) { + // Should be promoting based on initial sReg set + DCHECK_EQ(sReg, oatS2VReg(cUnit, sReg)); + if (cUnit->promotionMap[sReg+1].fpLocation == kLocPhysReg) { // Upper reg is already allocated. Can we fit? - int highReg = cUnit->regLocation[sReg+1].fpLowReg; + int highReg = cUnit->promotionMap[sReg+1].fpReg; if ((highReg & 1) == 0) { // High reg is even - fail. return res; @@ -289,12 +293,10 @@ STATIC int allocPreservedDouble(CompilationUnit* cUnit, int sReg) } } if (res != -1) { - cUnit->regLocation[sReg].fpLocation = kLocPhysReg; - cUnit->regLocation[sReg].fpLowReg = res; - cUnit->regLocation[sReg].home = true; - cUnit->regLocation[sReg+1].fpLocation = kLocPhysReg; - cUnit->regLocation[sReg+1].fpLowReg = res + 1; - cUnit->regLocation[sReg+1].home = true; + cUnit->promotionMap[sReg].fpLocation = kLocPhysReg; + cUnit->promotionMap[sReg].fpReg = res; + cUnit->promotionMap[sReg+1].fpLocation = kLocPhysReg; + cUnit->promotionMap[sReg+1].fpReg = res + 1; } return res; } @@ -312,7 +314,6 @@ extern int oatAllocPreservedFPReg(CompilationUnit* cUnit, int sReg, int res = -1; if (doubleStart) { res = allocPreservedDouble(cUnit, sReg); - } else { } if (res == -1) { res = allocPreservedSingle(cUnit, sReg, false /* try odd # */); diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc index aef98faff5..c4d3b6d780 100644 --- a/src/compiler/codegen/arm/ArchUtility.cc +++ b/src/compiler/codegen/arm/ArchUtility.cc @@ -16,6 +16,7 @@ #include "../../CompilerInternals.h" #include "ArmLIR.h" +#include "../Ralloc.h" static const char* coreRegNames[16] = { "r0", @@ -391,6 +392,38 @@ void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr) } } +void oatDumpPromotionMap(CompilationUnit *cUnit) +{ + const Method *method = cUnit->method; + for (int i = 0; i < method->NumRegisters(); i++) { + PromotionMap vRegMap = cUnit->promotionMap[i]; + char buf[100]; + if (vRegMap.fpLocation == kLocPhysReg) { + snprintf(buf, 100, " : s%d", vRegMap.fpReg & FP_REG_MASK); + } else { + buf[0] = 0; + } + char buf2[100]; + snprintf(buf2, 100, "V[%02d] -> %s%d%s", i, + vRegMap.coreLocation == kLocPhysReg ? + "r" : "SP+", vRegMap.coreLocation == kLocPhysReg ? + vRegMap.coreReg : oatSRegOffset(cUnit, i), buf); + LOG(INFO) << buf2; + } +} + +void oatDumpFullPromotionMap(CompilationUnit *cUnit) +{ + const Method *method = cUnit->method; + for (int i = 0; i < method->NumRegisters(); i++) { + PromotionMap vRegMap = cUnit->promotionMap[i]; + LOG(INFO) << i << " -> " << "CL:" << (int)vRegMap.coreLocation << + ", CR:" << (int)vRegMap.coreReg << ", FL:" << + (int)vRegMap.fpLocation << ", FR:" << (int)vRegMap.fpReg << + ", - " << (int)vRegMap.firstInPair; + } +} + /* Dump instructions and constant pool contents */ void oatCodegenDump(CompilationUnit* cUnit) { @@ -414,22 +447,7 @@ void oatCodegenDump(CompilationUnit* cUnit) " bytes, Dalvik size is " << insnsSize * 2; LOG(INFO) << "expansion factor: " << (float)cUnit->totalSize / (float)(insnsSize * 2); - for (int i = 0; i < method->NumRegisters(); i++) { - RegLocation loc = cUnit->regLocation[i]; - char buf[100]; - if (loc.fpLocation == kLocPhysReg) { - snprintf(buf, 100, " : s%d", loc.fpLowReg & FP_REG_MASK); - } else { - buf[0] = 0; - } - char buf2[100]; - snprintf(buf2, 100, "V[%02d] -> %s%d%s", i, - loc.location == kLocPhysReg ? - "r" : "SP+", loc.location == kLocPhysReg ? - loc.lowReg : loc.spOffset, buf); - LOG(INFO) << buf2; - - } + oatDumpPromotionMap(cUnit); for (lirInsn = cUnit->firstLIRInsn; lirInsn; lirInsn = lirInsn->next) { oatDumpLIRInsn(cUnit, lirInsn, 0); } diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h index 1e4022ee4b..729e708fad 100644 --- a/src/compiler/codegen/arm/ArmLIR.h +++ b/src/compiler/codegen/arm/ArmLIR.h @@ -123,16 +123,13 @@ #define rNone (-1) /* RegisterLocation templates return values (r0, or r0/r1) */ -#define LOC_C_RETURN {kLocPhysReg, 0, 0, r0, INVALID_REG, INVALID_SREG, \ - 1, kLocPhysReg, r0, INVALID_REG, INVALID_OFFSET} -#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, r0, r1, INVALID_SREG, \ - 1, kLocPhysReg, r0, r1, INVALID_OFFSET} +#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 1, r0, INVALID_REG, INVALID_SREG} +#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, r0, r1, INVALID_SREG} /* RegisterLocation templates for interpState->retVal; */ -#define LOC_DALVIK_RETURN_VAL {kLocPhysReg, 0, 0, r0, INVALID_REG, \ - INVALID_SREG, 1, kLocPhysReg, r0, INVALID_REG, \ - INVALID_OFFSET} -#define LOC_DALVIK_RETURN_VAL_WIDE {kLocPhysReg, 1, 0, r0, r1, \ - INVALID_SREG, 1, kLocPhysReg, r0, r1, INVALID_OFFSET} +#define LOC_DALVIK_RETURN_VAL {kLocPhysReg, 0, 0, 0, 0, 0, 1, r0, INVALID_REG, \ + INVALID_SREG} +#define LOC_DALVIK_RETURN_VAL_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, r0, r1, \ + INVALID_SREG} /* * Data structure tracking the mapping between a Dalvik register (pair) and a diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc index ed8a5b2ab3..4af3d0713a 100644 --- a/src/compiler/codegen/arm/ArmRallocUtil.cc +++ b/src/compiler/codegen/arm/ArmRallocUtil.cc @@ -37,7 +37,7 @@ typedef struct RefCounts { /* USE SSA names to count references of base Dalvik vRegs. */ STATIC void countRefs(CompilationUnit *cUnit, BasicBlock* bb, - RefCounts* counts, bool fp) + RefCounts* coreCounts, RefCounts* fpCounts) { MIR* mir; if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock && @@ -47,59 +47,42 @@ STATIC void countRefs(CompilationUnit *cUnit, BasicBlock* bb, for (mir = bb->firstMIRInsn; mir; mir = mir->next) { SSARepresentation *ssaRep = mir->ssaRep; if (ssaRep) { - int i; - int attrs = oatDataFlowAttributes[mir->dalvikInsn.opcode]; - if (fp) { - // Mark 1st reg of double pairs - int first = 0; - int sReg; - if ((attrs & (DF_DA_WIDE|DF_FP_A)) == (DF_DA_WIDE|DF_FP_A)) { - sReg = DECODE_REG( - oatConvertSSARegToDalvik(cUnit, ssaRep->defs[0])); - counts[sReg].doubleStart = true; + 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]); + if (loc.defined) { + counts[vReg].count++; } - if ((attrs & (DF_UA_WIDE|DF_FP_A)) == (DF_UA_WIDE|DF_FP_A)) { - sReg = DECODE_REG( - oatConvertSSARegToDalvik(cUnit, ssaRep->uses[first])); - counts[sReg].doubleStart = true; - } - if (attrs & DF_UA_WIDE) { - first += 2; - } - if ((attrs & (DF_UB_WIDE|DF_FP_B)) == (DF_UB_WIDE|DF_FP_B)) { - sReg = DECODE_REG( - oatConvertSSARegToDalvik(cUnit, ssaRep->uses[first])); - counts[sReg].doubleStart = true; - } - if (attrs & DF_UB_WIDE) { - first += 2; - } - if ((attrs & (DF_UC_WIDE|DF_FP_C)) == (DF_UC_WIDE|DF_FP_C)) { - sReg = DECODE_REG( - oatConvertSSARegToDalvik(cUnit, ssaRep->uses[first])); - counts[sReg].doubleStart = true; - } - } - for (i=0; i< ssaRep->numUses; i++) { - int origSreg = DECODE_REG( - oatConvertSSARegToDalvik(cUnit, ssaRep->uses[i])); - DCHECK_LT(origSreg, cUnit->method->NumRegisters()); - bool fpUse = ssaRep->fpUse ? ssaRep->fpUse[i] : false; - if (fp == fpUse) { - counts[origSreg].count++; + if (loc.wide) { + if (loc.defined) { + if (loc.fp) { + counts[vReg].doubleStart = true; + } + counts[vReg+1].count++; + } + i += 2; + } else { + i++; } } - for (i=0; i< ssaRep->numDefs; i++) { - if (attrs & DF_SETS_CONST) { - // CONST opcodes are untyped - don't pollute the counts - continue; + 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]); + if (loc.defined) { + counts[vReg].count++; } - int origSreg = DECODE_REG( - oatConvertSSARegToDalvik(cUnit, ssaRep->defs[i])); - DCHECK_LT(origSreg, cUnit->method->NumRegisters()); - bool fpDef = ssaRep->fpDef ? ssaRep->fpDef[i] : false; - if (fp == fpDef) { - counts[origSreg].count++; + if (loc.wide) { + if (loc.defined) { + if (loc.fp) { + counts[vReg].doubleStart = true; + } + counts[vReg+1].count++; + } + i += 2; + } else { + i++; } } } @@ -159,8 +142,7 @@ extern void oatDoPromotion(CompilationUnit* cUnit) BasicBlock* bb; bb = (BasicBlock*)oatGrowableListIteratorNext(&iterator); if (bb == NULL) break; - countRefs(cUnit, bb, coreRegs, false); - countRefs(cUnit, bb, fpRegs, true); + countRefs(cUnit, bb, coreRegs, fpRegs); } /* @@ -178,21 +160,27 @@ extern void oatDoPromotion(CompilationUnit* cUnit) qsort(coreRegs, numRegs, sizeof(RefCounts), sortCounts); qsort(fpRegs, numRegs, sizeof(RefCounts), sortCounts); + if (cUnit->printMe) { + dumpCounts(coreRegs, numRegs, "Core regs after sort"); + dumpCounts(fpRegs, numRegs, "Fp regs after sort"); + } + if (!(cUnit->disableOpt & (1 << kPromoteRegs))) { // Promote fpRegs for (int i = 0; (fpRegs[i].count > 0) && (i < numRegs); i++) { - if (cUnit->regLocation[fpRegs[i].sReg].fpLocation != kLocPhysReg) { + if (cUnit->promotionMap[fpRegs[i].sReg].fpLocation != kLocPhysReg) { int reg = oatAllocPreservedFPReg(cUnit, fpRegs[i].sReg, fpRegs[i].doubleStart); if (reg < 0) { - break; // No more left + break; // No more left } } } // Promote core regs for (int i = 0; (coreRegs[i].count > 0) && i < numRegs; i++) { - if (cUnit->regLocation[i].location != kLocPhysReg) { + if (cUnit->promotionMap[coreRegs[i].sReg].coreLocation != + kLocPhysReg) { int reg = oatAllocPreservedCoreReg(cUnit, coreRegs[i].sReg); if (reg < 0) { break; // No more left @@ -203,58 +191,69 @@ extern void oatDoPromotion(CompilationUnit* cUnit) // Now, update SSA names to new home locations for (int i = 0; i < cUnit->numSSARegs; i++) { - int baseSreg = cUnit->regLocation[i].sRegLow; - RegLocation *base = &cUnit->regLocation[baseSreg]; - RegLocation *baseNext = &cUnit->regLocation[baseSreg+1]; RegLocation *curr = &cUnit->regLocation[i]; - if (curr->fp) { - /* Single or double, check fpLocation of base */ - if (base->fpLocation == kLocPhysReg) { - if (curr->wide) { - /* TUNING: consider alignment during allocation */ - if ((base->fpLowReg & 1) || - (baseNext->fpLocation != kLocPhysReg)) { - /* Half-promoted or bad alignment - demote */ - curr->location = kLocDalvikFrame; - curr->lowReg = INVALID_REG; - curr->highReg = INVALID_REG; - continue; - } - curr->highReg = baseNext->fpLowReg; + int baseVReg = oatS2VReg(cUnit, curr->sRegLow); + if (!curr->wide) { + if (curr->fp) { + if (cUnit->promotionMap[baseVReg].fpLocation == kLocPhysReg) { + curr->location = kLocPhysReg; + curr->lowReg = cUnit->promotionMap[baseVReg].fpReg; + curr->home = true; + } + } else { + if (cUnit->promotionMap[baseVReg].coreLocation == kLocPhysReg) { + curr->location = kLocPhysReg; + curr->lowReg = cUnit->promotionMap[baseVReg].coreReg; + curr->home = true; } - curr->location = kLocPhysReg; - curr->lowReg = base->fpLowReg; - curr->home = true; } + curr->highReg = INVALID_REG; } else { - /* Core or wide */ - if (base->location == kLocPhysReg) { - if (curr->wide) { - /* Make sure upper half is also in reg or skip */ - if (baseNext->location != kLocPhysReg) { - /* Only half promoted; demote to frame */ - curr->location = kLocDalvikFrame; - curr->lowReg = INVALID_REG; - curr->highReg = INVALID_REG; - continue; + if (curr->highWord) { + continue; + } + if (curr->fp) { + if ((cUnit->promotionMap[baseVReg].fpLocation == kLocPhysReg) && + (cUnit->promotionMap[baseVReg+1].fpLocation == + kLocPhysReg)) { + int lowReg = cUnit->promotionMap[baseVReg].fpReg; + int highReg = cUnit->promotionMap[baseVReg+1].fpReg; + // Doubles require pair of singles starting at even reg + if (((lowReg & 0x1) == 0) && ((lowReg + 1) == highReg)) { + curr->location = kLocPhysReg; + curr->lowReg = lowReg; + curr->highReg = highReg; + curr->home = true; } - curr->highReg = baseNext->lowReg; } - curr->location = kLocPhysReg; - curr->lowReg = base->lowReg; - curr->home = true; + } else { + if ((cUnit->promotionMap[baseVReg].coreLocation == kLocPhysReg) + && (cUnit->promotionMap[baseVReg+1].coreLocation == + kLocPhysReg)) { + curr->location = kLocPhysReg; + curr->lowReg = cUnit->promotionMap[baseVReg].coreReg; + curr->highReg = cUnit->promotionMap[baseVReg+1].coreReg; + curr->home = true; + } } } } } -/* Returns sp-relative offset in bytes */ -extern int oatVRegOffset(CompilationUnit* cUnit, int reg) +/* Returns sp-relative offset in bytes for a VReg */ +extern int oatVRegOffset(CompilationUnit* cUnit, int vReg) { - return (reg < cUnit->numRegs) ? cUnit->regsOffset + (reg << 2) : - cUnit->insOffset + ((reg - cUnit->numRegs) << 2); + return (vReg < cUnit->numRegs) ? cUnit->regsOffset + (vReg << 2) : + cUnit->insOffset + ((vReg - cUnit->numRegs) << 2); } +/* Returns sp-relative offset in bytes for a SReg */ +extern int oatSRegOffset(CompilationUnit* cUnit, int sReg) +{ + return oatVRegOffset(cUnit, oatS2VReg(cUnit, sReg)); +} + + /* Return sp-relative offset in bytes using Method* */ extern int oatVRegOffsetFromMethod(Method* method, int reg) { diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc index 633125443b..4a657718fd 100644 --- a/src/compiler/codegen/arm/MethodCodegenDriver.cc +++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc @@ -17,10 +17,8 @@ #define DISPLAY_MISSING_TARGETS (cUnit->enableDebug & \ (1 << kDebugDisplayMissingTargets)) -STATIC const RegLocation badLoc = {kLocDalvikFrame, 0, 0, INVALID_REG, - INVALID_REG, INVALID_SREG, 0, - kLocDalvikFrame, INVALID_REG, INVALID_REG, - INVALID_OFFSET}; +STATIC const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, INVALID_REG, + INVALID_REG, INVALID_SREG}; /* Mark register usage state and return long retloc */ STATIC RegLocation getRetLocWide(CompilationUnit* cUnit) @@ -99,7 +97,8 @@ STATIC void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange) RegLocation loc = oatUpdateLoc(cUnit, oatGetSrc(cUnit, mir, i)); if (loc.location == kLocPhysReg) { - storeBaseDisp(cUnit, rSP, loc.spOffset, loc.lowReg, kWord); + storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, loc.sRegLow), + loc.lowReg, kWord); } } /* @@ -113,7 +112,8 @@ STATIC void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange) int rVal = rLR; // Using a lot of temps, rLR is known free here // Set up source pointer RegLocation rlFirst = oatGetSrc(cUnit, mir, 0); - opRegRegImm(cUnit, kOpAdd, rSrc, rSP, rlFirst.spOffset); + opRegRegImm(cUnit, kOpAdd, rSrc, rSP, + oatSRegOffset(cUnit, rlFirst.sRegLow)); // Set up the target pointer opRegRegImm(cUnit, kOpAdd, rDst, r0, Array::DataOffset().Int32Value()); @@ -773,7 +773,8 @@ STATIC int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir, } else { // r2 & r3 can safely be used here reg = r3; - loadWordDisp(cUnit, rSP, rlArg.spOffset + 4, reg); + loadWordDisp(cUnit, rSP, + oatSRegOffset(cUnit, rlArg.sRegLow) + 4, reg); callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback); } @@ -872,20 +873,23 @@ STATIC int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir, if (loc.wide) { loc = oatUpdateLocWide(cUnit, loc); if ((nextArg >= 2) && (loc.location == kLocPhysReg)) { - storeBaseDispWide(cUnit, rSP, loc.spOffset, loc.lowReg, - loc.highReg); + storeBaseDispWide(cUnit, rSP, + oatSRegOffset(cUnit, loc.sRegLow), + loc.lowReg, loc.highReg); } nextArg += 2; } else { loc = oatUpdateLoc(cUnit, loc); if ((nextArg >= 3) && (loc.location == kLocPhysReg)) { - storeBaseDisp(cUnit, rSP, loc.spOffset, loc.lowReg, kWord); + storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, loc.sRegLow), + loc.lowReg, kWord); } nextArg++; } } - int startOffset = cUnit->regLocation[mir->ssaRep->uses[3]].spOffset; + int startOffset = oatSRegOffset(cUnit, + cUnit->regLocation[mir->ssaRep->uses[3]].sRegLow); int outsOffset = 4 /* Method* */ + (3 * 4); if (numArgs >= 20) { // Generate memcpy @@ -1790,63 +1794,44 @@ STATIC void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir) } } -/* If there are any ins passed in registers that have not been promoted - * to a callee-save register, flush them to the frame. - * Note: at this pointCopy any ins that are passed in register to their - * home location */ +/* + * If there are any ins passed in registers that have not been promoted + * to a callee-save register, flush them to the frame. Perform intial + * assignment of promoted arguments. + */ STATIC void flushIns(CompilationUnit* cUnit) { if (cUnit->method->NumIns() == 0) return; - int inRegs = (cUnit->method->NumIns() > 2) ? 3 - : cUnit->method->NumIns(); - int startReg = r1; - int startLoc = cUnit->method->NumRegisters() - + int firstArgReg = r1; + int lastArgReg = r3; + int startVReg = cUnit->method->NumRegisters() - cUnit->method->NumIns(); - for (int i = 0; i < inRegs; i++) { - RegLocation loc = cUnit->regLocation[startLoc + i]; - //TUNING: be smarter about flushing ins to frame - storeBaseDisp(cUnit, rSP, loc.spOffset, startReg + i, kWord); - if (loc.location == kLocPhysReg) { - genRegCopy(cUnit, loc.lowReg, startReg + i); - } - } - - // Handle special case of wide argument half in regs, half in frame - if (inRegs == 3) { - RegLocation loc = cUnit->regLocation[startLoc + 2]; - if (loc.wide && loc.location == kLocPhysReg) { - // Load the other half of the arg into the promoted pair - loadWordDisp(cUnit, rSP, loc.spOffset + 4, loc.highReg); - inRegs++; - } - } - - // Now, do initial assignment of all promoted arguments passed in frame - for (int i = inRegs; i < cUnit->method->NumIns();) { - RegLocation loc = cUnit->regLocation[startLoc + i]; - if (loc.fpLocation == kLocPhysReg) { - loc.location = kLocPhysReg; - loc.fp = true; - loc.lowReg = loc.fpLowReg; - loc.highReg = loc.fpHighReg; - } - if (loc.location == kLocPhysReg) { - if (loc.wide) { - if (loc.fp && (loc.lowReg & 1) != 0) { - // Misaligned - need to load as a pair of singles - loadWordDisp(cUnit, rSP, loc.spOffset, loc.lowReg); - loadWordDisp(cUnit, rSP, loc.spOffset + 4, loc.highReg); - } else { - loadBaseDispWide(cUnit, NULL, rSP, loc.spOffset, - loc.lowReg, loc.highReg, INVALID_SREG); - } - i++; - } else { - loadWordDisp(cUnit, rSP, loc.spOffset, loc.lowReg); + for (int i = 0; i < cUnit->method->NumIns(); i++) { + PromotionMap vMap = cUnit->promotionMap[startVReg + i]; + // For arguments only, should have at most one promotion kind + DCHECK(!((vMap.coreLocation == kLocPhysReg) && + (vMap.fpLocation == kLocPhysReg))); + if (i <= (lastArgReg - firstArgReg)) { + // If arriving in register, copy or flush + if (vMap.coreLocation == kLocPhysReg) { + genRegCopy(cUnit, vMap.coreReg, firstArgReg + i); + } else if (vMap.fpLocation == kLocPhysReg) { + genRegCopy(cUnit, vMap.fpReg, firstArgReg + i); + } + // Also put a copy in memory in case we're partially promoted + storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i), + firstArgReg + i, kWord); + } else { + // If arriving in frame, initialize promoted target regs + if (vMap.coreLocation == kLocPhysReg) { + loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i), + vMap.coreReg); + } else if (vMap.fpLocation == kLocPhysReg) { + loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i), + vMap.fpReg); } } - i++; } } |