From b45252bc627dd6ceaff9a1998a5379452cf80e29 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 24 Apr 2014 10:09:13 +0800 Subject: [PATCH] GBE: refine the gen program strategy. The limitRegisterPressure only affects the MAD pattern matching which could not bring noticeable difference here. I change it to always be false. And add the reserved registers for spill to the strategy structure. Thus we can try to build a program as the following strategy: 1. SIMD16 without spilling 2. SIMD16 with 10 spilling registers and with a default spilling threshold value 16. When need to spill more than 16 registers, we fall back to next method. 3. SIMD8 without spilling 4. SIMD8 with 8 spilling registers. Signed-off-by: Zhigang Gong Reviewed-by: "Song, Ruiling" --- backend/src/backend/gen_context.cpp | 4 +++- backend/src/backend/gen_context.hpp | 4 +++- backend/src/backend/gen_insn_selection.cpp | 4 ++-- backend/src/backend/gen_program.cpp | 15 ++++++++------- backend/src/backend/gen_reg_allocation.cpp | 9 ++++----- backend/src/backend/gen_reg_allocation.hpp | 1 - 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp index 838bddd..34e3e61 100644 --- a/backend/src/backend/gen_context.cpp +++ b/backend/src/backend/gen_context.cpp @@ -46,9 +46,11 @@ namespace gbe GenContext::GenContext(const ir::Unit &unit, const std::string &name, uint32_t deviceID, + uint32_t reservedSpillRegs, bool limitRegisterPressure, bool relaxMath) : - Context(unit, name), deviceID(deviceID), limitRegisterPressure(limitRegisterPressure), relaxMath(relaxMath) + Context(unit, name), deviceID(deviceID), reservedSpillRegs(reservedSpillRegs), + limitRegisterPressure(limitRegisterPressure), relaxMath(relaxMath) { this->p = GBE_NEW(GenEncoder, simdWidth, 7, deviceID); // XXX handle more than Gen7 this->sel = GBE_NEW(Selection, *this); diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp index 1154796..12434f5 100644 --- a/backend/src/backend/gen_context.hpp +++ b/backend/src/backend/gen_context.hpp @@ -52,7 +52,8 @@ namespace gbe /*! Create a new context. name is the name of the function we want to * compile */ - GenContext(const ir::Unit &unit, const std::string &name, uint32_t deviceID, bool limitRegisterPressure = false, bool relaxMath = false); + GenContext(const ir::Unit &unit, const std::string &name, uint32_t deviceID, uint32_t reservedSpillRegs = 0, + bool limitRegisterPressure = false, bool relaxMath = false); /*! Release everything needed */ ~GenContext(void); /*! Target device ID*/ @@ -175,6 +176,7 @@ namespace gbe /*! Indicate if we need to tackle a register pressure issue when * regenerating the code */ + uint32_t reservedSpillRegs; bool limitRegisterPressure; bool relaxMath; private: diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp index 8c7ac09..32086d3 100644 --- a/backend/src/backend/gen_insn_selection.cpp +++ b/backend/src/backend/gen_insn_selection.cpp @@ -739,7 +739,7 @@ namespace gbe } } - if (poolOffset > RESERVED_REG_NUM_FOR_SPILL) { + if (poolOffset > ctx.reservedSpillRegs) { std::cerr << "Instruction (#" << (uint32_t)insn.opcode << ") src too large pooloffset " << (uint32_t)poolOffset << std::endl; return false; } @@ -797,7 +797,7 @@ namespace gbe } } - if (poolOffset > RESERVED_REG_NUM_FOR_SPILL){ + if (poolOffset > ctx.reservedSpillRegs){ std::cerr << "Instruction (#" << (uint32_t)insn.opcode << ") dst too large pooloffset " << (uint32_t)poolOffset << std::endl; return false; } diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp index 240ae4f..4dca79d 100644 --- a/backend/src/backend/gen_program.cpp +++ b/backend/src/backend/gen_program.cpp @@ -76,12 +76,13 @@ namespace gbe { /*! We must avoid spilling at all cost with Gen */ static const struct CodeGenStrategy { uint32_t simdWidth; + uint32_t reservedSpillRegs; bool limitRegisterPressure; } codeGenStrategy[] = { - {16,false}, - {16,true}, - {8,false}, - {8,true}, + {16, 0, false}, + {16, 10, false}, + {8, 0, false}, + {8, 8, false}, }; Kernel *GenProgram::compileKernel(const ir::Unit &unit, const std::string &name, bool relaxMath) { @@ -98,10 +99,11 @@ namespace gbe { for (; codeGen < codeGenNum; ++codeGen) { const uint32_t simdWidth = codeGenStrategy[codeGen].simdWidth; const bool limitRegisterPressure = codeGenStrategy[codeGen].limitRegisterPressure; + const uint32_t reservedSpillRegs = codeGenStrategy[codeGen].reservedSpillRegs; // Force the SIMD width now and try to compile unit.getFunction(name)->setSimdWidth(simdWidth); - Context *ctx = GBE_NEW(GenContext, unit, name, deviceID, limitRegisterPressure, relaxMath); + Context *ctx = GBE_NEW(GenContext, unit, name, deviceID, reservedSpillRegs, limitRegisterPressure, relaxMath); kernel = ctx->compileKernel(); if (kernel != NULL) { break; @@ -110,8 +112,7 @@ namespace gbe { fn->getImageSet()->clearInfo(); } - // XXX spill must be implemented - GBE_ASSERTM(kernel != NULL, "Register spilling not supported yet!"); + GBE_ASSERTM(kernel != NULL, "Fail to compile kernel, may need to increase reserved registers for spilling."); return kernel; } diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp index c45fed7..32cd643 100644 --- a/backend/src/backend/gen_reg_allocation.cpp +++ b/backend/src/backend/gen_reg_allocation.cpp @@ -627,7 +627,7 @@ namespace gbe const uint32_t grfOffset = allocateReg(interval, size, alignment); if(grfOffset == 0) { GBE_ASSERT(!(reservedReg && family != ir::FAMILY_DWORD)); - GBE_ASSERT(vector->regNum < RESERVED_REG_NUM_FOR_SPILL); + GBE_ASSERT(ctx.reservedSpillRegs == 0 || vector->regNum < ctx.reservedSpillRegs); for(int i = vector->regNum-1; i >= 0; i--) { if (!spillReg(vector->reg[i].reg())) return false; @@ -893,12 +893,11 @@ namespace gbe INLINE bool GenRegAllocator::Opaque::allocate(Selection &selection) { using namespace ir; - if (ctx.getSimdWidth() == 8) { - reservedReg = ctx.allocate(RESERVED_REG_NUM_FOR_SPILL * GEN_REG_SIZE, GEN_REG_SIZE); + if (ctx.reservedSpillRegs != 0) { + reservedReg = ctx.allocate(ctx.reservedSpillRegs * GEN_REG_SIZE, GEN_REG_SIZE); reservedReg /= GEN_REG_SIZE; } else { - reservedReg = ctx.allocate(RESERVED_REG_NUM_FOR_SPILL * GEN_REG_SIZE, GEN_REG_SIZE); - reservedReg /= GEN_REG_SIZE; + reservedReg = 0; } // schedulePreRegAllocation(ctx, selection); diff --git a/backend/src/backend/gen_reg_allocation.hpp b/backend/src/backend/gen_reg_allocation.hpp index a2a1d40..e41f503 100644 --- a/backend/src/backend/gen_reg_allocation.hpp +++ b/backend/src/backend/gen_reg_allocation.hpp @@ -27,7 +27,6 @@ #include "ir/register.hpp" #include "backend/gen_register.hpp" -#define RESERVED_REG_NUM_FOR_SPILL 8 namespace gbe { -- 2.7.4