[Beignet] [PATCH 1/2] GBE: Avoid unecessary dag/liveness computing at backend.
Zhigang Gong
zhigang.gong at intel.com
Thu Apr 24 03:18:39 PDT 2014
We don't need to compute dag/liveness at the backend when
we switch to a new code gen strategy.
For the unit test case, this patch could save 15% of the
overall execution time. For the luxmark with STRICT conformance
mode, it saves about 40% of the build time.
Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
backend/src/backend/context.cpp | 27 +++++++++++++++++++--------
backend/src/backend/context.hpp | 2 ++
backend/src/backend/gen_context.cpp | 23 ++++++++++++++++-------
backend/src/backend/gen_context.hpp | 5 +++--
backend/src/backend/gen_program.cpp | 8 ++++++--
5 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp
index dc27d83..377356a 100644
--- a/backend/src/backend/context.cpp
+++ b/backend/src/backend/context.cpp
@@ -335,12 +335,8 @@ namespace gbe
this->liveness = GBE_NEW(ir::Liveness, const_cast<ir::Function&>(fn));
this->dag = GBE_NEW(ir::FunctionDAG, *this->liveness);
// r0 (GEN_REG_SIZE) is always set by the HW and used at the end by EOT
- this->registerAllocator = GBE_NEW(RegisterAllocator, GEN_REG_SIZE, 4*KB - GEN_REG_SIZE);
- this->scratchAllocator = GBE_NEW(ScratchAllocator, 12*KB);
- if (fn.getSimdWidth() == 0 || OCL_SIMD_WIDTH != 15)
- this->simdWidth = nextHighestPowerOf2(OCL_SIMD_WIDTH);
- else
- this->simdWidth = fn.getSimdWidth();
+ this->registerAllocator = NULL; //GBE_NEW(RegisterAllocator, GEN_REG_SIZE, 4*KB - GEN_REG_SIZE);
+ this->scratchAllocator = NULL; //GBE_NEW(ScratchAllocator, 12*KB);
}
Context::~Context(void) {
@@ -350,12 +346,27 @@ namespace gbe
GBE_SAFE_DELETE(this->liveness);
}
+ void Context::startNewCG(uint32_t simdWidth) {
+ if (simdWidth == 0 || OCL_SIMD_WIDTH != 15)
+ this->simdWidth = nextHighestPowerOf2(OCL_SIMD_WIDTH);
+ else
+ this->simdWidth = simdWidth;
+ GBE_SAFE_DELETE(this->registerAllocator);
+ GBE_SAFE_DELETE(this->scratchAllocator);
+ GBE_ASSERT(dag != NULL && liveness != NULL);
+ this->registerAllocator = GBE_NEW(RegisterAllocator, GEN_REG_SIZE, 4*KB - GEN_REG_SIZE);
+ this->scratchAllocator = GBE_NEW(ScratchAllocator, 12*KB);
+ this->curbeRegs.clear();
+ }
+
Kernel *Context::compileKernel(void) {
this->kernel = this->allocateKernel();
this->kernel->simdWidth = this->simdWidth;
this->buildArgList();
- this->buildUsedLabels();
- this->buildJIPs();
+ if (usedLabels.size() == 0)
+ this->buildUsedLabels();
+ if (JIPs.size() == 0)
+ this->buildJIPs();
this->buildStack();
this->handleSLM();
if (this->emitCode() == false) {
diff --git a/backend/src/backend/context.hpp b/backend/src/backend/context.hpp
index 26167a0..d4dcfca 100644
--- a/backend/src/backend/context.hpp
+++ b/backend/src/backend/context.hpp
@@ -56,6 +56,8 @@ namespace gbe
Context(const ir::Unit &unit, const std::string &name);
/*! Release everything needed */
virtual ~Context(void);
+ /*! start new code generation with specific simd width. */
+ void startNewCG(uint32_t simdWidth);
/*! Compile the code */
Kernel *compileKernel(void);
/*! Tells if the labels is used */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 34e3e61..f399353 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -46,15 +46,12 @@ 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), reservedSpillRegs(reservedSpillRegs),
- limitRegisterPressure(limitRegisterPressure), relaxMath(relaxMath)
+ Context(unit, name), deviceID(deviceID), relaxMath(relaxMath)
{
- this->p = GBE_NEW(GenEncoder, simdWidth, 7, deviceID); // XXX handle more than Gen7
- this->sel = GBE_NEW(Selection, *this);
- this->ra = GBE_NEW(GenRegAllocator, *this);
+ this->p = NULL;
+ this->sel = NULL;
+ this->ra = NULL;
}
GenContext::~GenContext(void) {
@@ -63,6 +60,18 @@ namespace gbe
GBE_DELETE(this->p);
}
+ void GenContext::startNewCG(uint32_t simdWidth, uint32_t reservedSpillRegs, bool limitRegisterPressure) {
+ this->limitRegisterPressure = limitRegisterPressure;
+ this->reservedSpillRegs = reservedSpillRegs;
+ Context::startNewCG(simdWidth);
+ GBE_SAFE_DELETE(ra);
+ GBE_SAFE_DELETE(sel);
+ GBE_SAFE_DELETE(p);
+ this->p = GBE_NEW(GenEncoder, this->simdWidth, 7, deviceID); // XXX handle more than Gen7
+ this->sel = GBE_NEW(Selection, *this);
+ this->ra = GBE_NEW(GenRegAllocator, *this);
+ }
+
void GenContext::emitInstructionStream(void) {
// Emit Gen ISA
for (auto &block : *sel->blockList)
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
index 12434f5..14ea719 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -52,10 +52,11 @@ 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, uint32_t reservedSpillRegs = 0,
- bool limitRegisterPressure = false, bool relaxMath = false);
+ GenContext(const ir::Unit &unit, const std::string &name, uint32_t deviceID, bool relaxMath = false);
/*! Release everything needed */
~GenContext(void);
+ /*! Start new code generation with specific parameters */
+ void startNewCG(uint32_t simdWidth, uint32_t reservedSpillRegs, bool limitRegisterPressure);
/*! Target device ID*/
uint32_t deviceID;
/*! Implements base class */
diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp
index 4dca79d..ccfeff2 100644
--- a/backend/src/backend/gen_program.cpp
+++ b/backend/src/backend/gen_program.cpp
@@ -80,9 +80,12 @@ namespace gbe {
bool limitRegisterPressure;
} codeGenStrategy[] = {
{16, 0, false},
+ {16, 5, false},
{16, 10, false},
{8, 0, false},
+ {8, 4, false},
{8, 8, false},
+ {8, 16, false},
};
Kernel *GenProgram::compileKernel(const ir::Unit &unit, const std::string &name, bool relaxMath) {
@@ -96,6 +99,7 @@ namespace gbe {
Kernel *kernel = NULL;
// Stop when compilation is successful
+ GenContext *ctx = GBE_NEW(GenContext, unit, name, deviceID, relaxMath);
for (; codeGen < codeGenNum; ++codeGen) {
const uint32_t simdWidth = codeGenStrategy[codeGen].simdWidth;
const bool limitRegisterPressure = codeGenStrategy[codeGen].limitRegisterPressure;
@@ -103,14 +107,14 @@ namespace gbe {
// Force the SIMD width now and try to compile
unit.getFunction(name)->setSimdWidth(simdWidth);
- Context *ctx = GBE_NEW(GenContext, unit, name, deviceID, reservedSpillRegs, limitRegisterPressure, relaxMath);
+ ctx->startNewCG(simdWidth, reservedSpillRegs, limitRegisterPressure);
kernel = ctx->compileKernel();
if (kernel != NULL) {
break;
}
- GBE_DELETE(ctx);
fn->getImageSet()->clearInfo();
}
+ //GBE_DELETE(ctx);
GBE_ASSERTM(kernel != NULL, "Fail to compile kernel, may need to increase reserved registers for spilling.");
return kernel;
--
1.8.3.2
More information about the Beignet
mailing list