summaryrefslogtreecommitdiff
path: root/src/compiler/codegen/RallocUtil.cc
diff options
context:
space:
mode:
author buzbee <buzbee@google.com> 2011-10-02 13:08:29 -0700
committer buzbee <buzbee@google.com> 2011-10-02 13:21:01 -0700
commitbbaf894dded77603bd457758ba2b4636122fb8b7 (patch)
treeac8d0450f23dd6cde9647febef8de514c5a4b8ae /src/compiler/codegen/RallocUtil.cc
parentfc22c89072e310767f8e39776195a219df851ea0 (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.cc43
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;
}
}