GBE: move the image info register allocation to GEN IR stage.
authorZhigang Gong <zhigang.gong@intel.com>
Thu, 16 Jan 2014 03:56:15 +0000 (11:56 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Fri, 17 Jan 2014 06:27:46 +0000 (14:27 +0800)
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@intel.com>
Reviewed-by: "Yang, Rong R" <rong.r.yang@intel.com>
backend/src/backend/context.cpp
backend/src/backend/gen_context.cpp
backend/src/backend/gen_insn_gen7_schedule_info.hxx
backend/src/backend/gen_insn_selection.hxx
backend/src/backend/gen_reg_allocation.cpp
backend/src/ir/image.cpp
backend/src/ir/image.hpp
backend/src/ir/instruction.hpp
backend/src/llvm/llvm_gen_backend.cpp

index 1941689..7a80dc8 100644 (file)
@@ -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) {
index ea7a9f1..6a9461b 100644 (file)
@@ -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) {
index bb70b16..13cbd41 100644 (file)
@@ -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)
index 0118619..e44b9d4 100644 (file)
@@ -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)
index 7365e02..b42aed8 100644 (file)
@@ -142,8 +142,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();
index af43ac7..8c34d70 100644 (file)
@@ -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;
index 088e479..cf388d4 100644 (file)
@@ -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 */
index a9d9adf..66b64dd 100644 (file)
@@ -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 */
index 5fb6db1..b0555aa 100644 (file)
@@ -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: