From 4f7d506a7d34228ca608bdba0041e39316b0d37a Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 24 Jan 2014 12:33:10 +0800 Subject: [PATCH] GBE: refine register allocation output. Signed-off-by: Zhigang Gong --- backend/src/backend/gen_reg_allocation.cpp | 75 ++++++++++++++++-------------- backend/src/ir/register.hpp | 5 ++ 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp index fedd730..22f2608 100644 --- a/backend/src/backend/gen_reg_allocation.cpp +++ b/backend/src/backend/gen_reg_allocation.cpp @@ -58,6 +58,20 @@ namespace gbe GenRegister genReg(const GenRegister ®); /*! Output the register allocation */ void outputAllocation(void); + INLINE void getRegAttrib(ir::Register reg, uint32_t ®Size, ir::RegisterFamily *regFamily = NULL) const { + // Note that byte vector registers use two bytes per byte (and can be + // interleaved) + static const size_t familyVectorSize[] = {2,2,2,4,8}; + static const size_t familyScalarSize[] = {2,1,2,4,8}; + using namespace ir; + const bool isScalar = ctx.sel->isScalarOrBool(reg); + const RegisterData regData = ctx.sel->getRegisterData(reg); + const RegisterFamily family = regData.family; + const uint32_t typeSize = isScalar ? familyScalarSize[family] : familyVectorSize[family]; + regSize = isScalar ? typeSize : ctx.getSimdWidth() * typeSize; + if (regFamily != NULL) + *regFamily = family; + } private: /*! Expire one GRF interval. Return true if one was successfully expired */ bool expireGRF(const GenRegInterval &limit); @@ -108,10 +122,6 @@ namespace gbe GBE_CLASS(Opaque); }; - // Note that byte vector registers use two bytes per byte (and can be - // interleaved) - static const size_t familyVectorSize[] = {2,2,2,4,8}; - static const size_t familyScalarSize[] = {2,1,2,4,8}; /*! Interval as used in linear scan allocator. Basically, stores the first and * the last instruction where the register is alive @@ -164,15 +174,11 @@ namespace gbe bool GenRegAllocator::Opaque::createGenReg(const GenRegInterval &interval) { using namespace ir; const ir::Register reg = interval.reg; - const uint32_t simdWidth = ctx.getSimdWidth(); if (RA.contains(reg) == true) return true; // already allocated GBE_ASSERT(ctx.isScalarReg(reg) == false); - const bool isScalar = ctx.sel->isScalarOrBool(reg); - const RegisterData regData = ctx.sel->getRegisterData(reg); - const RegisterFamily family = regData.family; - const uint32_t typeSize = isScalar ? familyScalarSize[family] : familyVectorSize[family]; - const uint32_t regSize = isScalar ? typeSize : simdWidth*typeSize; + uint32_t regSize; + getRegAttrib(reg, regSize); uint32_t grfOffset; while ((grfOffset = ctx.allocate(regSize, regSize)) == 0) { const bool success = this->expireGRF(interval); @@ -494,13 +500,10 @@ namespace gbe // all the reg in the SelectionVector are spilled if(spilled.contains(vector->reg[0].reg())) continue; - const uint32_t simdWidth = ctx.getSimdWidth(); - - const ir::RegisterData regData = ctx.sel->getRegisterData(reg); - const ir::RegisterFamily family = regData.family; - const uint32_t typeSize = familyVectorSize[family]; - const uint32_t alignment = simdWidth*typeSize; + uint32_t alignment; + ir::RegisterFamily family; + getRegAttrib(reg, alignment, &family); const uint32_t size = vector->regNum * alignment; uint32_t grfOffset; @@ -680,32 +683,34 @@ namespace gbe cout << "## register allocation ##" << endl; for(auto &i : RA) { ir::Register vReg = (ir::Register)i.first; + ir::RegisterFamily family; + uint32_t regSize; + getRegAttrib(vReg, regSize, &family); int offst = (int)i.second;// / sizeof(float); - ir::RegisterData regData = ctx.sel->getRegisterData(vReg); int reg = offst / 32; - int subreg = offst % 32; - ir::RegisterFamily family = regData.family; - int registerSize; - if (family == ir::FAMILY_BOOL) - registerSize = 2; - else { - registerSize = ir::getFamilySize(regData.family); - if (!ctx.isScalarReg(vReg)) - registerSize *= ctx.getSimdWidth(); - } + int subreg = (offst % 32) / regSize; cout << "%" << setiosflags(ios::left) << setw(8) << vReg << "g" << setiosflags(ios::left) << setw(3) << reg << "." - << setiosflags(ios::left) << setw(2) << subreg - << " " << setw(3) << registerSize << "B" - << " [" << setw(8) << this->intervals[(uint)vReg].minID + << setiosflags(ios::left) << setw(3) << subreg << ir::getFamilyName(family) + << " " << setw(-3) << regSize << "B\t" + << "[ " << setw(8) << this->intervals[(uint)vReg].minID << " -> " << setw(8) << this->intervals[(uint)vReg].maxID << "]" << endl; } - std::set::iterator is; - std::cout << "## spilled registers:" << std::endl; - for(is = spilled.begin(); is != spilled.end(); is++) - std::cout << (int)*is << std::endl; - std::cout << std::endl; + cout << "## spilled registers:" << endl; + for(auto is = spilled.begin(); is != spilled.end(); is++) { + ir::Register vReg = (ir::Register)*is; + ir::RegisterFamily family; + uint32_t regSize; + getRegAttrib(vReg, regSize, &family); + cout << "%" << setiosflags(ios::left) << setw(8) << vReg + << " " << ir::getFamilyName(family) + << " " << setw(-3) << regSize << "B\t" + << "[ " << setw(8) << this->intervals[(uint)vReg].minID + << " -> " << setw(8) << this->intervals[(uint)vReg].maxID + << "]" << endl; + } + cout << endl; } INLINE GenRegister setGenReg(const GenRegister &src, uint32_t grfOffset) { diff --git a/backend/src/ir/register.hpp b/backend/src/ir/register.hpp index 610acb1..4f36c2e 100644 --- a/backend/src/ir/register.hpp +++ b/backend/src/ir/register.hpp @@ -47,6 +47,11 @@ namespace ir { FAMILY_QWORD = 4 }; + INLINE char getFamilyName(RegisterFamily family) { + static char registerFamilyName[] = {'b', 'B', 'W', 'D', 'Q'}; + return registerFamilyName[family]; + } + INLINE uint32_t getFamilySize(RegisterFamily family) { switch (family) { case FAMILY_BYTE: return 1; -- 2.7.4