diff options
| author | Bill Buzbee <buzbee@google.com> | 2010-03-02 16:14:41 -0800 |
|---|---|---|
| committer | Bill Buzbee <buzbee@google.com> | 2010-03-03 15:13:17 -0800 |
| commit | 1f74863d3e0f19930818398f375ebf1cf2d78969 (patch) | |
| tree | 4e646a4e73cae7d5e98c621d1cc1aa330a466cf9 /vm/compiler/codegen/arm/RallocUtil.c | |
| parent | 10ebc7d0b84dcb98e1a7eeac96ef06acdfc8d184 (diff) | |
Jit: Sapphire tuning - mostly scheduling.
Re-enabled load/store motion that had inadvertently been turned off for
non-armv7 targets. Tagged memory references with the kind of memory
they touch (Dalvik frame, literal pool, heap) to enable more aggressive
load hoisting. Eliminated some largely duplicate code in the target
specific files. Reworked temp register allocation code to allocate next
temp round-robin (to improve scheduling opportunities).
Overall, nice gain for Sapphire. Shows 5% to 15% on some benchmarks, and
measurable improvements for Passion.
Diffstat (limited to 'vm/compiler/codegen/arm/RallocUtil.c')
| -rw-r--r-- | vm/compiler/codegen/arm/RallocUtil.c | 108 |
1 files changed, 67 insertions, 41 deletions
diff --git a/vm/compiler/codegen/arm/RallocUtil.c b/vm/compiler/codegen/arm/RallocUtil.c index 9035f93c7..131df2c7b 100644 --- a/vm/compiler/codegen/arm/RallocUtil.c +++ b/vm/compiler/codegen/arm/RallocUtil.c @@ -123,7 +123,7 @@ static RegisterInfo *getRegInfo(CompilationUnit *cUnit, int reg) } } LOGE("Tried to get info on a non-existant temp: r%d",reg); - dvmAbort(); + dvmAbort(); // FIXME: abort translation intead of vm return NULL; } @@ -218,29 +218,38 @@ extern void dvmCompilerClobberSReg(CompilationUnit *cUnit, int sReg) } static int allocTempBody(CompilationUnit *cUnit, RegisterInfo *p, int numTemps, - bool required) + int *nextTemp, bool required) { int i; - //Tuning: redo this to widen the live window on freed temps + int next = *nextTemp; for (i=0; i< numTemps; i++) { - if (!p[i].inUse && !p[i].live) { - dvmCompilerClobber(cUnit, p[i].reg); - p[i].inUse = true; - p[i].pair = false; - return p[i].reg; + if (next >= numTemps) + next = 0; + if (!p[next].inUse && !p[next].live) { + dvmCompilerClobber(cUnit, p[next].reg); + p[next].inUse = true; + p[next].pair = false; + *nextTemp = next + 1; + return p[next].reg; } + next++; } + next = *nextTemp; for (i=0; i< numTemps; i++) { - if (!p[i].inUse) { - dvmCompilerClobber(cUnit, p[i].reg); - p[i].inUse = true; - p[i].pair = false; - return p[i].reg; + if (next >= numTemps) + next = 0; + if (!p[next].inUse) { + dvmCompilerClobber(cUnit, p[next].reg); + p[next].inUse = true; + p[next].pair = false; + *nextTemp = next + 1; + return p[next].reg; } + next++; } if (required) { LOGE("No free temp registers"); - assert(0); + dvmAbort(); // FIXME: abort translation instead of vm } return -1; // No register available } @@ -250,34 +259,46 @@ extern int dvmCompilerAllocTempDouble(CompilationUnit *cUnit) { RegisterInfo *p = cUnit->regPool->FPTemps; int numTemps = cUnit->regPool->numFPTemps; + int next = cUnit->regPool->nextFPTemp; int i; for (i=0; i < numTemps; i+=2) { - if ((!p[i].inUse && !p[i].live) && - (!p[i+1].inUse && !p[i+1].live)) { - dvmCompilerClobber(cUnit, p[i].reg); - dvmCompilerClobber(cUnit, p[i+1].reg); - p[i].inUse = true; - p[i+1].inUse = true; - assert((p[i].reg+1) == p[i+1].reg); - assert((p[i].reg & 0x1) == 0); - return p[i].reg; + /* Cleanup - not all targets need aligned regs */ + if (next & 1) + next++; + if (next >= numTemps) + next = 0; + if ((!p[next].inUse && !p[next].live) && + (!p[next+1].inUse && !p[next+1].live)) { + dvmCompilerClobber(cUnit, p[next].reg); + dvmCompilerClobber(cUnit, p[next+1].reg); + p[next].inUse = true; + p[next+1].inUse = true; + assert((p[next].reg+1) == p[next+1].reg); + assert((p[next].reg & 0x1) == 0); + cUnit->regPool->nextFPTemp += 2; + return p[next].reg; } + next += 2; } + next = cUnit->regPool->nextFPTemp; for (i=0; i < numTemps; i+=2) { - if (!p[i].inUse && !p[i+1].inUse) { - dvmCompilerClobber(cUnit, p[i].reg); - dvmCompilerClobber(cUnit, p[i+1].reg); - p[i].inUse = true; - p[i+1].inUse = true; - assert((p[i].reg+1) == p[i+1].reg); - assert((p[i].reg & 0x1) == 0); - return p[i].reg; + if (next >= numTemps) + next = 0; + if (!p[next].inUse && !p[next+1].inUse) { + dvmCompilerClobber(cUnit, p[next].reg); + dvmCompilerClobber(cUnit, p[next+1].reg); + p[next].inUse = true; + p[next+1].inUse = true; + assert((p[next].reg+1) == p[next+1].reg); + assert((p[next].reg & 0x1) == 0); + cUnit->regPool->nextFPTemp += 2; + return p[next].reg; } + next += 2; } LOGE("No free temp registers"); - *((int*)0) = 0; //For development, die instantly. Later abort translation - dvmAbort(); + dvmAbort(); // FIXME: abort translation instead of vm return -1; } @@ -285,19 +306,22 @@ extern int dvmCompilerAllocTempDouble(CompilationUnit *cUnit) extern int dvmCompilerAllocFreeTemp(CompilationUnit *cUnit) { return allocTempBody(cUnit, cUnit->regPool->coreTemps, - cUnit->regPool->numCoreTemps, true); + cUnit->regPool->numCoreTemps, + &cUnit->regPool->nextCoreTemp, true); } extern int dvmCompilerAllocTemp(CompilationUnit *cUnit) { return allocTempBody(cUnit, cUnit->regPool->coreTemps, - cUnit->regPool->numCoreTemps, true); + cUnit->regPool->numCoreTemps, + &cUnit->regPool->nextCoreTemp, true); } extern int dvmCompilerAllocTempFloat(CompilationUnit *cUnit) { return allocTempBody(cUnit, cUnit->regPool->FPTemps, - cUnit->regPool->numFPTemps, true); + cUnit->regPool->numFPTemps, + &cUnit->regPool->nextFPTemp, true); } static RegisterInfo *allocLiveBody(RegisterInfo *p, int numTemps, int sReg) @@ -335,8 +359,7 @@ static RegisterInfo *allocLive(CompilationUnit *cUnit, int sReg, break; default: LOGE("Invalid register type"); - assert(0); - dvmAbort(); + dvmAbort(); //FIXME: abort translation instead of vm } return res; } @@ -363,10 +386,13 @@ extern void dvmCompilerFreeTemp(CompilationUnit *cUnit, int reg) } } LOGE("Tried to free a non-existant temp: r%d",reg); - dvmAbort(); + dvmAbort(); // FIXME: abort translation instead of vm } -//FIXME - this needs to also check the preserved pool. +/* + * FIXME - this needs to also check the preserved pool once we start + * start using preserved registers. + */ extern RegisterInfo *dvmCompilerIsLive(CompilationUnit *cUnit, int reg) { RegisterInfo *p = cUnit->regPool->coreTemps; @@ -434,7 +460,7 @@ extern void dvmCompilerLockTemp(CompilationUnit *cUnit, int reg) } } LOGE("Tried to lock a non-existant temp: r%d",reg); - dvmAbort(); + dvmAbort(); // FIXME: abort translation instead of vm } static void lockArgRegs(CompilationUnit *cUnit) |
