From 142a45e602c612d0c7c73806c8038da7c56b9ac0 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 16 Jan 2014 11:56:15 +0800 Subject: [PATCH] GBE: move the image info register allocation to GEN IR stage. 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 Reviewed-by: "Yang, Rong R" --- backend/src/backend/context.cpp | 14 +++----------- backend/src/backend/gen_context.cpp | 17 ----------------- backend/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(insn).getImageIndex(); const unsigned char type = ir::cast(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 7365e02..b42aed8 100644 --- a/backend/src/backend/gen_reg_allocation.cpp +++ b/backend/src/backend/gen_reg_allocation.cpp @@ -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(); 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 regMap; map indexMap; + map 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: -- 2.7.4