[Beignet] [PATCH] GBE: refine the gen program strategy.

Zhigang Gong zhigang.gong at intel.com
Wed Apr 23 19:25:13 PDT 2014


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 <zhigang.gong at intel.com>
---
 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
 {
-- 
1.8.3.2



More information about the Beignet mailing list