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);
/*! 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*/
/*! Indicate if we need to tackle a register pressure issue when
* regenerating the code
*/
+ uint32_t reservedSpillRegs;
bool limitRegisterPressure;
bool relaxMath;
private:
}
}
- 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;
}
}
}
- 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;
}
/*! 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) {
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;
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;
}
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;
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);
#include "ir/register.hpp"
#include "backend/gen_register.hpp"
-#define RESERVED_REG_NUM_FOR_SPILL 8
namespace gbe
{