diff options
| author | 2011-10-07 14:02:25 -0700 | |
|---|---|---|
| committer | 2011-10-07 14:16:01 -0700 | |
| commit | 6825326abfef92d4e1bf6afddef1a319aa18d08c (patch) | |
| tree | 1706bf3e0bbdb9f7a704140f70011c1b362fa294 | |
| parent | a43cb5e8fb29989dbb986b9b91a68cda150aa3c8 (diff) | |
Reg utility fix
Long ago in a galaxy far away, there was a trace compiler that
handled short code fragments with a small, sparse and variable
set of temp registers. In that situation, doing linear reg
lookups wasn't terrible. In the new world that has a fixed and
packed set of registers, a linear search is unnecessary, foolish
and wasteful. [P.S. perf showed that roughly 25% of all
compilation time was spent doing register manipulation!]
Change-Id: I6f23d9f70367fb4139cc28a27fd9fdf8beffa270
| -rw-r--r-- | src/compiler/codegen/Ralloc.h | 1 | ||||
| -rw-r--r-- | src/compiler/codegen/RallocUtil.cc | 114 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArmRallocUtil.cc | 6 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Factory.cc | 2 |
4 files changed, 44 insertions, 79 deletions
diff --git a/src/compiler/codegen/Ralloc.h b/src/compiler/codegen/Ralloc.h index e87da884df..e343ec5682 100644 --- a/src/compiler/codegen/Ralloc.h +++ b/src/compiler/codegen/Ralloc.h @@ -235,4 +235,5 @@ extern int oatVRegOffset(CompilationUnit* cUnit, int reg); extern void oatDumpCoreRegPool(CompilationUnit* cUint); extern void oatDumpFPRegPool(CompilationUnit* cUint); extern bool oatCheckCorePoolSanity(CompilationUnit* cUnit); +extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg); #endif // ART_SRC_COMPILER_RALLOC_H_ diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc index 9d3717a279..7fd062d5a5 100644 --- a/src/compiler/codegen/RallocUtil.cc +++ b/src/compiler/codegen/RallocUtil.cc @@ -97,32 +97,10 @@ void oatDumpFpRegPool(CompilationUnit* cUnit) dumpRegPool(cUnit->regPool->FPRegs, cUnit->regPool->numFPRegs); } -/* Get info for a reg. */ -STATIC RegisterInfo* getRegInfo(CompilationUnit* cUnit, int reg) -{ - int numRegs = cUnit->regPool->numCoreRegs; - RegisterInfo* p = cUnit->regPool->coreRegs; - int i; - for (i=0; i< numRegs; i++) { - if (p[i].reg == reg) { - return &p[i]; - } - } - p = cUnit->regPool->FPRegs; - numRegs = cUnit->regPool->numFPRegs; - for (i=0; i< numRegs; i++) { - if (p[i].reg == reg) { - return &p[i]; - } - } - LOG(FATAL) << "Tried to get info on a non-existant reg :r" << reg; - return NULL; // Quiet gcc -} - void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2) { - RegisterInfo* info1 = getRegInfo(cUnit, reg1); - RegisterInfo* info2 = getRegInfo(cUnit, reg2); + RegisterInfo* info1 = oatGetRegInfo(cUnit, reg1); + RegisterInfo* info2 = oatGetRegInfo(cUnit, reg2); DCHECK(info1 && info2 && info1->pair && info2->pair && (info1->partner == info2->reg) && (info2->partner == info1->reg)); @@ -146,7 +124,7 @@ void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2) void oatFlushReg(CompilationUnit* cUnit, int reg) { - RegisterInfo* info = getRegInfo(cUnit, reg); + RegisterInfo* info = oatGetRegInfo(cUnit, reg); if (info->live && info->dirty) { info->dirty = false; int vReg = oatS2VReg(cUnit, info->sReg); @@ -156,40 +134,20 @@ void oatFlushReg(CompilationUnit* cUnit, int reg) } } -/* return true if found reg to clobber */ -STATIC bool clobberRegBody(CompilationUnit* cUnit, RegisterInfo* p, - int numRegs, int reg) -{ - int i; - for (i=0; i< numRegs; i++) { - if (p[i].reg == reg) { - if (p[i].isTemp) { - if (p[i].live && p[i].dirty) { - LOG(FATAL) << "Live & dirty temp in clobber"; - } - p[i].live = false; - p[i].sReg = INVALID_SREG; - } - p[i].defStart = NULL; - p[i].defEnd = NULL; - if (p[i].pair) { - p[i].pair = false; - /* partners should be in same pool */ - clobberRegBody(cUnit, p, numRegs, p[i].partner); - } - return true; - } - } - return false; -} - /* Mark a temp register as dead. Does not affect allocation state. */ void oatClobber(CompilationUnit* cUnit, int reg) { - if (!clobberRegBody(cUnit, cUnit->regPool->coreRegs, - cUnit->regPool->numCoreRegs, reg)) { - clobberRegBody(cUnit, cUnit->regPool->FPRegs, - cUnit->regPool->numFPRegs, reg); + RegisterInfo* p = oatGetRegInfo(cUnit, reg); + if (p->isTemp) { + DCHECK(!(p->live && p->dirty)) << "Live & dirty temp in clobber"; + p->live = false; + p->sReg = INVALID_SREG; + p->defStart = NULL; + p->defEnd = NULL; + if (p->pair) { + p->pair = false; + oatClobber(cUnit, p->partner); + } } } @@ -302,7 +260,7 @@ STATIC int allocPreservedDouble(CompilationUnit* cUnit, int sReg) return res; } // Is the low reg of the pair free? - RegisterInfo* p = getRegInfo(cUnit, highReg-1); + RegisterInfo* p = oatGetRegInfo(cUnit, highReg-1); if (p->inUse || p->isTemp) { // Already allocated or not preserved - fail. return res; @@ -563,19 +521,19 @@ extern RegisterInfo* oatIsLive(CompilationUnit* cUnit, int reg) extern RegisterInfo* oatIsTemp(CompilationUnit* cUnit, int reg) { - RegisterInfo* p = getRegInfo(cUnit, reg); + RegisterInfo* p = oatGetRegInfo(cUnit, reg); return (p->isTemp) ? p : NULL; } extern RegisterInfo* oatIsPromoted(CompilationUnit* cUnit, int reg) { - RegisterInfo* p = getRegInfo(cUnit, reg); + RegisterInfo* p = oatGetRegInfo(cUnit, reg); return (p->isTemp) ? NULL : p; } extern bool oatIsDirty(CompilationUnit* cUnit, int reg) { - RegisterInfo* p = getRegInfo(cUnit, reg); + RegisterInfo* p = oatGetRegInfo(cUnit, reg); return p->dirty; } @@ -612,7 +570,7 @@ extern void oatLockTemp(CompilationUnit* cUnit, int reg) extern void oatResetDef(CompilationUnit* cUnit, int reg) { - RegisterInfo* p = getRegInfo(cUnit, reg); + RegisterInfo* p = oatGetRegInfo(cUnit, reg); p->defStart = NULL; p->defEnd = NULL; } @@ -643,7 +601,7 @@ extern void oatMarkDef(CompilationUnit* cUnit, RegLocation rl, DCHECK(!rl.wide); DCHECK(start && start->next); DCHECK(finish); - RegisterInfo* p = getRegInfo(cUnit, rl.lowReg); + RegisterInfo* p = oatGetRegInfo(cUnit, rl.lowReg); p->defStart = start->next; p->defEnd = finish; } @@ -659,7 +617,7 @@ extern void oatMarkDefWide(CompilationUnit* cUnit, RegLocation rl, DCHECK(rl.wide); DCHECK(start && start->next); DCHECK(finish); - RegisterInfo* p = getRegInfo(cUnit, rl.lowReg); + RegisterInfo* p = oatGetRegInfo(cUnit, rl.lowReg); oatResetDef(cUnit, rl.highReg); // Only track low of pair p->defStart = start->next; p->defEnd = finish; @@ -670,8 +628,8 @@ extern RegLocation oatWideToNarrow(CompilationUnit* cUnit, { DCHECK(rl.wide); if (rl.location == kLocPhysReg) { - RegisterInfo* infoLo = getRegInfo(cUnit, rl.lowReg); - RegisterInfo* infoHi = getRegInfo(cUnit, rl.highReg); + RegisterInfo* infoLo = oatGetRegInfo(cUnit, rl.lowReg); + RegisterInfo* infoHi = oatGetRegInfo(cUnit, rl.highReg); if (infoLo->isTemp) { infoLo->pair = false; infoLo->defStart = NULL; @@ -798,7 +756,7 @@ STATIC bool regClassMatches(int regClass, int reg) extern void oatMarkLive(CompilationUnit* cUnit, int reg, int sReg) { - RegisterInfo* info = getRegInfo(cUnit, reg); + RegisterInfo* info = oatGetRegInfo(cUnit, reg); if ((info->reg == reg) && (info->sReg == sReg) && info->live) { return; /* already live */ } else if (sReg != INVALID_SREG) { @@ -816,20 +774,20 @@ extern void oatMarkLive(CompilationUnit* cUnit, int reg, int sReg) extern void oatMarkTemp(CompilationUnit* cUnit, int reg) { - RegisterInfo* info = getRegInfo(cUnit, reg); + RegisterInfo* info = oatGetRegInfo(cUnit, reg); info->isTemp = true; } extern void oatUnmarkTemp(CompilationUnit* cUnit, int reg) { - RegisterInfo* info = getRegInfo(cUnit, reg); + RegisterInfo* info = oatGetRegInfo(cUnit, reg); info->isTemp = false; } extern void oatMarkPair(CompilationUnit* cUnit, int lowReg, int highReg) { - RegisterInfo* infoLo = getRegInfo(cUnit, lowReg); - RegisterInfo* infoHi = getRegInfo(cUnit, highReg); + RegisterInfo* infoLo = oatGetRegInfo(cUnit, lowReg); + RegisterInfo* infoHi = oatGetRegInfo(cUnit, highReg); infoLo->pair = infoHi->pair = true; infoLo->partner = highReg; infoHi->partner = lowReg; @@ -837,10 +795,10 @@ extern void oatMarkPair(CompilationUnit* cUnit, int lowReg, int highReg) extern void oatMarkClean(CompilationUnit* cUnit, RegLocation loc) { - RegisterInfo* info = getRegInfo(cUnit, loc.lowReg); + RegisterInfo* info = oatGetRegInfo(cUnit, loc.lowReg); info->dirty = false; if (loc.wide) { - info = getRegInfo(cUnit, loc.highReg); + info = oatGetRegInfo(cUnit, loc.highReg); info->dirty = false; } } @@ -851,24 +809,24 @@ extern void oatMarkDirty(CompilationUnit* cUnit, RegLocation loc) // If already home, can't be dirty return; } - RegisterInfo* info = getRegInfo(cUnit, loc.lowReg); + RegisterInfo* info = oatGetRegInfo(cUnit, loc.lowReg); info->dirty = true; if (loc.wide) { - info = getRegInfo(cUnit, loc.highReg); + info = oatGetRegInfo(cUnit, loc.highReg); info->dirty = true; } } extern void oatMarkInUse(CompilationUnit* cUnit, int reg) { - RegisterInfo* info = getRegInfo(cUnit, reg); + RegisterInfo* info = oatGetRegInfo(cUnit, reg); info->inUse = true; } STATIC void copyRegInfo(CompilationUnit* cUnit, int newReg, int oldReg) { - RegisterInfo* newInfo = getRegInfo(cUnit, newReg); - RegisterInfo* oldInfo = getRegInfo(cUnit, oldReg); + RegisterInfo* newInfo = oatGetRegInfo(cUnit, newReg); + RegisterInfo* oldInfo = oatGetRegInfo(cUnit, oldReg); // Target temp status must not change bool isTemp = newInfo->isTemp; *newInfo = *oldInfo; @@ -915,7 +873,7 @@ bool oatCheckCorePoolSanity(CompilationUnit* cUnit) static int myReg = cUnit->regPool->coreRegs[i].reg; static int mySreg = cUnit->regPool->coreRegs[i].sReg; static int partnerReg = cUnit->regPool->coreRegs[i].partner; - static RegisterInfo* partner = getRegInfo(cUnit, partnerReg); + static RegisterInfo* partner = oatGetRegInfo(cUnit, partnerReg); DCHECK(partner != NULL); DCHECK(partner->pair); DCHECK_EQ(myReg, partner->partner); diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc index 94852e391f..ed8a5b2ab3 100644 --- a/src/compiler/codegen/arm/ArmRallocUtil.cc +++ b/src/compiler/codegen/arm/ArmRallocUtil.cc @@ -322,3 +322,9 @@ extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit) oatMarkInUse(cUnit, r1); return res; } + +extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg) +{ + return FPREG(reg) ? &cUnit->regPool->FPRegs[reg & FP_REG_MASK] + : &cUnit->regPool->coreRegs[reg]; +} diff --git a/src/compiler/codegen/arm/Thumb2/Factory.cc b/src/compiler/codegen/arm/Thumb2/Factory.cc index 45c7377988..318be5abcf 100644 --- a/src/compiler/codegen/arm/Thumb2/Factory.cc +++ b/src/compiler/codegen/arm/Thumb2/Factory.cc @@ -22,7 +22,7 @@ * */ -static int coreRegs[] = {r0, r1, r2, r3, rSUSPEND, r5, r6, r7, rSELF, r8, r10, +static int coreRegs[] = {r0, r1, r2, r3, rSUSPEND, r5, r6, r7, r8, rSELF, r10, r11, r12, rSP, rLR, rPC}; static int reservedRegs[] = {rSUSPEND, rSELF, rSP, rLR, rPC}; static int fpRegs[] = {fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7, |