diff options
| author | 2011-10-02 13:08:29 -0700 | |
|---|---|---|
| committer | 2011-10-02 13:21:01 -0700 | |
| commit | bbaf894dded77603bd457758ba2b4636122fb8b7 (patch) | |
| tree | ac8d0450f23dd6cde9647febef8de514c5a4b8ae /src/compiler/codegen/RallocUtil.cc | |
| parent | fc22c89072e310767f8e39776195a219df851ea0 (diff) | |
Optimization fixes
Two primary fixes. First, the save/restore mechanism for FP callee saves
was broken if there were any holes in the save mask (the Arm ld/store
multiple instructions for floating point use a start + count mechanism,
rather than the bit-mask mechanism used for core registers).
The second fix corrects a problem introduced by the recent enhancements
to loading floating point literals. The load->copy optimization mechanism
for literal loads used the value of the loaded literal to identify
redundant loads. However, it used only the first 32 bits of the
literal - which worked fine previously because 64-bit literal loads
were treated as a pair of 32-bit loads. The fix was to use the
label of the literal rather than the value in the aliasInfo - which
works for all sizes.
Change-Id: Ic4779adf73b2c7d80059a988b0ecdef39921a81f
Diffstat (limited to 'src/compiler/codegen/RallocUtil.cc')
| -rw-r--r-- | src/compiler/codegen/RallocUtil.cc | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc index 9df80bd49b..969028779c 100644 --- a/src/compiler/codegen/RallocUtil.cc +++ b/src/compiler/codegen/RallocUtil.cc @@ -227,7 +227,7 @@ extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sReg) coreRegs[i].inUse = true; cUnit->coreSpillMask |= (1 << res); cUnit->coreVmapTable.push_back(sReg); - cUnit->numSpills++; + cUnit->numCoreSpills++; cUnit->regLocation[sReg].location = kLocPhysReg; cUnit->regLocation[sReg].lowReg = res; cUnit->regLocation[sReg].home = true; @@ -238,6 +238,28 @@ extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sReg) } /* + * Mark a callee-save fp register as promoted. Note that + * vpush/vpop uses contiguous register lists so we must + * include any holes in the mask. Associate holes with + * Dalvik register INVALID_REG (-1). + */ +STATIC void markPreservedSingle(CompilationUnit* cUnit, int sReg, int reg) +{ + DCHECK_GE(reg, FP_REG_MASK + FP_CALLEE_SAVE_BASE); + reg = (reg & FP_REG_MASK) - FP_CALLEE_SAVE_BASE; + // Ensure fpVmapTable is large enough + int tableSize = cUnit->fpVmapTable.size(); + for (int i = tableSize; i < (reg + 1); i++) { + cUnit->fpVmapTable.push_back(INVALID_REG); + } + // Add the current mapping + cUnit->fpVmapTable[reg] = sReg; + // Size of fpVmapTable is high-water mark, use to set mask + cUnit->numFPSpills = cUnit->fpVmapTable.size(); + cUnit->fpSpillMask = ((1 << cUnit->numFPSpills) - 1) << FP_CALLEE_SAVE_BASE; +} + +/* * Reserve a callee-save fp single register. Try to fullfill request for * even/odd allocation, but go ahead and allocate anything if not * available. If nothing's available, return -1. @@ -251,10 +273,7 @@ STATIC int allocPreservedSingle(CompilationUnit* cUnit, int sReg, bool even) ((FPRegs[i].reg & 0x1) == 0) == even) { res = FPRegs[i].reg; FPRegs[i].inUse = true; - cUnit->fpSpillMask |= (1 << (res & FP_REG_MASK)); - cUnit->fpVmapTable.push_back(sReg); - cUnit->numSpills++; - cUnit->numFPSpills++; + markPreservedSingle(cUnit, sReg, res); cUnit->regLocation[sReg].fpLocation = kLocPhysReg; cUnit->regLocation[sReg].fpLowReg = res; cUnit->regLocation[sReg].home = true; @@ -292,10 +311,7 @@ STATIC int allocPreservedDouble(CompilationUnit* cUnit, int sReg) res = p->reg; p->inUse = true; DCHECK_EQ((res & 1), 0); - cUnit->fpSpillMask |= (1 << (res & FP_REG_MASK)); - cUnit->fpVmapTable.push_back(sReg); - cUnit->numSpills++; - cUnit->numFPSpills ++; + markPreservedSingle(cUnit, sReg, res); } else { RegisterInfo* FPRegs = cUnit->regPool->FPRegs; for (int i = 0; i < cUnit->regPool->numFPRegs; i++) { @@ -306,13 +322,10 @@ STATIC int allocPreservedDouble(CompilationUnit* cUnit, int sReg) (FPRegs[i].reg + 1) == FPRegs[i+1].reg) { res = FPRegs[i].reg; FPRegs[i].inUse = true; - cUnit->fpSpillMask |= (1 << (res & FP_REG_MASK)); - cUnit->fpVmapTable.push_back(sReg); + markPreservedSingle(cUnit, sReg, res); FPRegs[i+1].inUse = true; - cUnit->fpSpillMask |= (1 << ((res+1) & FP_REG_MASK)); - cUnit->fpVmapTable.push_back(sReg); - cUnit->numSpills += 2; - cUnit->numFPSpills += 2; + DCHECK_EQ(res + 1, FPRegs[i+1].reg); + markPreservedSingle(cUnit, sReg+1, res+1); break; } } |