[Beignet] [PATCH 4/4] GBE: move the image info register allocation to GEN IR stage.

Zhigang Gong zhigang.gong at intel.com
Wed Jan 15 22:00:37 PST 2014


If we allocate image infor register at code generation stage,
we miss the liveness calculation. Thus there is a potential risk
that some image information register's livenss data is incorrect and
may cause very subtle bug. Now fix it.

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/backend/context.cpp                    |   14 +++-----------
 backend/src/backend/gen_context.cpp                |   17 -----------------
 .../src/backend/gen_insn_gen7_schedule_info.hxx    |    1 -
 backend/src/backend/gen_insn_selection.hxx         |    1 -
 backend/src/backend/gen_reg_allocation.cpp         |    3 +--
 backend/src/ir/image.cpp                           |   10 ++++++++++
 backend/src/ir/image.hpp                           |    3 +++
 backend/src/ir/instruction.hpp                     |    3 ++-
 backend/src/llvm/llvm_gen_backend.cpp              |    5 +++--
 9 files changed, 22 insertions(+), 35 deletions(-)

diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp
index 1941689..7a80dc8 100644
--- a/backend/src/backend/context.cpp
+++ b/backend/src/backend/context.cpp
@@ -472,19 +472,11 @@ namespace gbe
           if (srcID != 0) continue;
           const unsigned char bti = ir::cast<ir::GetImageInfoInstruction>(insn).getImageIndex();
           const unsigned char type =  ir::cast<ir::GetImageInfoInstruction>(insn).getInfoType();;
-          ir::ImageInfoKey key;
-          key.index = bti;
-          key.type = type;
-          const ir::Register imageInfo(key.data | 0x8000);
-          ir::Register realImageInfo;
+          ir::ImageInfoKey key(bti, type);
+          const ir::Register imageInfo = insn.getSrc(0);
           if (curbeRegs.find(imageInfo) == curbeRegs.end()) {
             uint32_t offset = this->getImageInfoCurbeOffset(key, 4);
-            realImageInfo = insn.getSrc(0);
-            insertCurbeReg(realImageInfo, offset);
-            insertCurbeReg(imageInfo, (uint32_t)realImageInfo);
-          } else {
-            realImageInfo = ir::Register(curbeRegs.find(imageInfo)->second);
-            insn.setSrc(0, realImageInfo);
+            insertCurbeReg(imageInfo, offset);
           }
           continue;
         } else if (insn.getOpcode() == ir::OP_GET_SAMPLER_INFO) {
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index ea7a9f1..6a9461b 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -1862,23 +1862,6 @@ namespace gbe
     p->pop();
   }
 
-  void GenContext::emitGetImageInfoInstruction(const SelectionInstruction &insn) {
-    const unsigned char bti = insn.extra.function;
-    const unsigned char type = insn.extra.elem;
-    const uint32_t dstNum = ir::GetImageInfoInstruction::getDstNum4Type(type);
-    ir::ImageInfoKey key;
-    key.index = bti;
-    key.type = type;
-
-    uint32_t offset = this->getImageInfoCurbeOffset(key, dstNum * 4) + GEN_REG_SIZE;
-    for(uint32_t i = 0; i < dstNum; i++) {
-      const uint32_t nr = offset / GEN_REG_SIZE;
-      const uint32_t subnr = (offset % GEN_REG_SIZE) / sizeof(uint32_t);
-      p->MOV(ra->genReg(insn.dst(i)), GenRegister::ud1grf(nr, subnr));
-      offset += 32;
-    }
-  }
-
   BVAR(OCL_OUTPUT_REG_ALLOC, false);
   BVAR(OCL_OUTPUT_ASM, false);
   bool GenContext::emitCode(void) {
diff --git a/backend/src/backend/gen_insn_gen7_schedule_info.hxx b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
index bb70b16..13cbd41 100644
--- a/backend/src/backend/gen_insn_gen7_schedule_info.hxx
+++ b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
@@ -34,7 +34,6 @@ DECL_GEN7_SCHEDULE(Sample,          80,        1,        1)
 DECL_GEN7_SCHEDULE(TypedWrite,      80,        1,        1)
 DECL_GEN7_SCHEDULE(SpillReg,        80,        1,        1)
 DECL_GEN7_SCHEDULE(UnSpillReg,      80,        1,        1)
-DECL_GEN7_SCHEDULE(GetImageInfo,    20,        4,        2)
 DECL_GEN7_SCHEDULE(Atomic,          80,        1,        1)
 DECL_GEN7_SCHEDULE(I64MUL,          20,        4,        2)
 DECL_GEN7_SCHEDULE(I64SATADD,       20,        4,        2)
diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
index 0118619..e44b9d4 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -60,7 +60,6 @@ DECL_SELECTION_IR(BYTE_SCATTER, ByteScatterInstruction)
 DECL_SELECTION_IR(DWORD_GATHER, DWordGatherInstruction)
 DECL_SELECTION_IR(SAMPLE, SampleInstruction)
 DECL_SELECTION_IR(TYPED_WRITE, TypedWriteInstruction)
-DECL_SELECTION_IR(GET_IMAGE_INFO, GetImageInfoInstruction)
 DECL_SELECTION_IR(SPILL_REG, SpillRegInstruction)
 DECL_SELECTION_IR(UNSPILL_REG, UnSpillRegInstruction)
 DECL_SELECTION_IR(MUL_HI, BinaryWithTempInstruction)
diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp
index f3dc7ac..9362795 100644
--- a/backend/src/backend/gen_reg_allocation.cpp
+++ b/backend/src/backend/gen_reg_allocation.cpp
@@ -140,8 +140,7 @@ namespace gbe
   INLINE void GenRegAllocator::Opaque::allocatePayloadRegs(void) {
     using namespace ir;
     for(auto &it : this->ctx.curbeRegs)
-      if (it.first.value() < 0x8000)
-        allocatePayloadReg(it.first, it.second);
+      allocatePayloadReg(it.first, it.second);
 
     // Allocate all pushed registers (i.e. structure kernel arguments)
     const Function &fn = ctx.getFunction();
diff --git a/backend/src/ir/image.cpp b/backend/src/ir/image.cpp
index af43ac7..8c34d70 100644
--- a/backend/src/ir/image.cpp
+++ b/backend/src/ir/image.cpp
@@ -64,6 +64,16 @@ namespace ir {
     setInfoOffset4Type(imageInfo, key.type, offset);
   }
 
+  Register ImageSet::appendInfo(ImageInfoKey key, Context *ctx)
+  {
+    auto it = infoRegMap.find(key.data);
+    if (it != infoRegMap.end())
+      return it->second;
+    Register reg = ctx->reg(FAMILY_DWORD);
+    infoRegMap.insert(std::make_pair(key.data, reg));
+    return reg;
+  }
+
   void ImageSet::clearInfo()
   {
     struct ImageInfo *imageInfo;
diff --git a/backend/src/ir/image.hpp b/backend/src/ir/image.hpp
index 088e479..cf388d4 100644
--- a/backend/src/ir/image.hpp
+++ b/backend/src/ir/image.hpp
@@ -47,6 +47,8 @@ namespace ir {
     void append(Register imageReg, Context *ctx);
     /*! Append an image info slot. */
     void appendInfo(ImageInfoKey key, uint32_t offset);
+    /*! Append an image info register. */
+    Register appendInfo(ImageInfoKey, Context *ctx);
     /*! clear image info. */
     void clearInfo();
     /*! Get the image's index(actual location). */
@@ -88,6 +90,7 @@ namespace ir {
   private:
     map<Register, struct ImageInfo *> regMap;
     map<uint32_t, struct ImageInfo *> indexMap;
+    map<uint32_t, Register> infoRegMap;
     GBE_CLASS(ImageSet);
   };
 } /* namespace ir */
diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp
index a9d9adf..66b64dd 100644
--- a/backend/src/ir/instruction.hpp
+++ b/backend/src/ir/instruction.hpp
@@ -373,7 +373,8 @@ namespace ir {
     static bool isClassOf(const Instruction &insn);
   };
 
-  typedef union {
+  typedef union _ImageInfoKey{
+    _ImageInfoKey(uint8_t i, uint8_t t) : index(i), type(t) {};
     struct {
      uint8_t index; /*! the allocated image index */
      uint8_t  type;  /*! the information type */
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 5fb6db1..b0555aa 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -2362,9 +2362,10 @@ namespace gbe
             GBE_ASSERT(AI != AE); const ir::Register surfaceReg = this->getRegister(*AI); ++AI;
             const ir::Register reg = this->getRegister(&I, 0);
             int infoType = it->second - GEN_OCL_GET_IMAGE_WIDTH;
-
             const uint8_t surfaceID = ctx.getFunction().getImageSet()->getIdx(surfaceReg);
-            ctx.GET_IMAGE_INFO(infoType, reg, surfaceID, ctx.reg(ir::FAMILY_DWORD));
+            ir::ImageInfoKey key(surfaceID, infoType);
+            const ir::Register infoReg = ctx.getFunction().getImageSet()->appendInfo(key, &ctx);
+            ctx.GET_IMAGE_INFO(infoType, reg, surfaceID, infoReg);
             break;
           }
           case GEN_OCL_GET_SAMPLER_INFO:
-- 
1.7.9.5



More information about the Beignet mailing list