From 767b115b0f4e8168fc0a086837f9a50aefeb5fa4 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 16 Jan 2014 10:16:36 +0800 Subject: [PATCH] GBE: move the image allocation to the GEN IR stage. Image register should be translate to a const at the GEN IR stage to avoid the register allocator to allocate unnecessary register for the image id. Signed-off-by: Zhigang Gong Reviewed-by: "Yang, Rong R" --- backend/src/backend/context.cpp | 6 +-- backend/src/backend/gen_insn_selection.cpp | 43 ++++++----------- backend/src/ir/instruction.cpp | 77 +++++++++++++++++------------- backend/src/ir/instruction.hpp | 9 ++-- backend/src/llvm/llvm_gen_backend.cpp | 21 ++++---- 5 files changed, 79 insertions(+), 77 deletions(-) diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp index 5a01132..1941689 100644 --- a/backend/src/backend/context.cpp +++ b/backend/src/backend/context.cpp @@ -470,7 +470,7 @@ namespace gbe const ir::Register reg = insn.getSrc(srcID); if (insn.getOpcode() == ir::OP_GET_IMAGE_INFO) { if (srcID != 0) continue; - const unsigned char bti = fn.getImageSet()->getIdx(insn.getSrc(srcID)); + const unsigned char bti = ir::cast(insn).getImageIndex(); const unsigned char type = ir::cast(insn).getInfoType();; ir::ImageInfoKey key; key.index = bti; @@ -479,12 +479,12 @@ namespace gbe ir::Register realImageInfo; if (curbeRegs.find(imageInfo) == curbeRegs.end()) { uint32_t offset = this->getImageInfoCurbeOffset(key, 4); - realImageInfo = insn.getSrc(1); + realImageInfo = insn.getSrc(0); insertCurbeReg(realImageInfo, offset); insertCurbeReg(imageInfo, (uint32_t)realImageInfo); } else { realImageInfo = ir::Register(curbeRegs.find(imageInfo)->second); - insn.setSrc(1, realImageInfo); + insn.setSrc(0, realImageInfo); } continue; } else if (insn.getOpcode() == ir::OP_GET_SAMPLER_INFO) { diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp index 0118ae4..74480aa 100644 --- a/backend/src/backend/gen_insn_selection.cpp +++ b/backend/src/backend/gen_insn_selection.cpp @@ -1390,17 +1390,6 @@ namespace gbe msgVector->reg = &insn->src(0); } - void Selection::Opaque::GET_IMAGE_INFO(uint32_t infoType, GenRegister *dst, - uint32_t dstNum, uint32_t bti) { - SelectionInstruction *insn = this->appendInsn(SEL_OP_GET_IMAGE_INFO, dstNum, 0); - - for(uint32_t i = 0; i < dstNum; ++i) - insn->dst(i) = dst[i]; - - insn->extra.function = bti; - insn->extra.elem = infoType; - } - Selection::~Selection(void) { GBE_DELETE(this->opaque); } void Selection::select(void) { @@ -2933,10 +2922,10 @@ namespace gbe { using namespace ir; GenRegister msgPayloads[4]; - GenRegister dst[insn.getDstNum()], src[insn.getSrcNum() - 1]; + GenRegister dst[insn.getDstNum()], src[insn.getSrcNum()]; uint32_t srcNum = insn.getSrcNum(); uint32_t samplerOffset = 0; - if (srcNum == 5) { + if (srcNum == 4) { /* We have the clamp border workaround. */ samplerOffset = insn.getSrc(srcNum - 1).value() * 8; srcNum--; @@ -2948,14 +2937,13 @@ namespace gbe for (uint32_t valueID = 0; valueID < insn.getDstNum(); ++valueID) dst[valueID] = sel.selReg(insn.getDst(valueID), insn.getDstType()); - for (uint32_t valueID = 0; valueID < srcNum - 1; ++valueID) - src[valueID] = sel.selReg(insn.getSrc(valueID + 1), insn.getSrcType()); + for (uint32_t valueID = 0; valueID < srcNum; ++valueID) + src[valueID] = sel.selReg(insn.getSrc(valueID), insn.getSrcType()); - uint32_t bti = sel.ctx.getFunction().getImageSet()->getIdx - (insn.getSrc(0)); + uint32_t bti = insn.getImageIndex(); uint32_t sampler = insn.getSamplerIndex() + samplerOffset; - sel.SAMPLE(dst, insn.getDstNum(), src, srcNum - 1, msgPayloads, 4, bti, sampler); + sel.SAMPLE(dst, insn.getDstNum(), src, srcNum, msgPayloads, 4, bti, sampler); return true; } DECL_CTOR(SampleInstruction, 1, 1); @@ -2968,25 +2956,24 @@ namespace gbe { using namespace ir; const uint32_t simdWidth = sel.ctx.getSimdWidth(); - uint32_t valueID = 0; + uint32_t valueID; GenRegister msgs[9]; // (header + U + V + R + LOD + 4) GenRegister src[insn.getSrcNum()]; uint32_t msgNum = (8 / (simdWidth / 8)) + 1; - uint32_t coordNum = (insn.getSrcNum() == 7) ? 2 : 3; + uint32_t coordNum = (insn.getSrcNum() == 6) ? 2 : 3; for(uint32_t i = 0; i < msgNum; i++) msgs[i] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32); // u, v, w coords should use coord type. - for (; valueID < coordNum; ++valueID) - src[valueID] = sel.selReg(insn.getSrc(valueID + 1), insn.getCoordType()); + for (valueID = 0; valueID < coordNum; ++valueID) + src[valueID] = sel.selReg(insn.getSrc(valueID), insn.getCoordType()); - for (; (valueID + 1) < insn.getSrcNum(); ++valueID) - src[valueID] = sel.selReg(insn.getSrc(valueID + 1), insn.getSrcType()); + for (; valueID < insn.getSrcNum(); ++valueID) + src[valueID] = sel.selReg(insn.getSrc(valueID), insn.getSrcType()); - uint32_t bti = sel.ctx.getFunction().getImageSet()->getIdx - (insn.getSrc(TypedWriteInstruction::SURFACE_BTI)); - sel.TYPED_WRITE(src, insn.getSrcNum() - 1, msgs, msgNum, bti); + uint32_t bti = insn.getImageIndex(); + sel.TYPED_WRITE(src, insn.getSrcNum(), msgs, msgNum, bti); return true; } DECL_CTOR(TypedWriteInstruction, 1, 1); @@ -3000,7 +2987,7 @@ namespace gbe using namespace ir; GenRegister dst; dst = sel.selReg(insn.getDst(0), TYPE_U32); - GenRegister imageInfoReg = GenRegister::ud1grf(insn.getSrc(1)); + GenRegister imageInfoReg = GenRegister::ud1grf(insn.getSrc(0)); sel.MOV(dst, imageInfoReg); return true; diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp index 182b95e..3a532ea 100644 --- a/backend/src/ir/instruction.cpp +++ b/backend/src/ir/instruction.cpp @@ -491,23 +491,24 @@ namespace ir { public TupleDstPolicy { public: - SampleInstruction(Tuple dstTuple, Tuple srcTuple, bool dstIsFloat, bool srcIsFloat, uint8_t sampler) { + SampleInstruction(uint8_t imageIdx, Tuple dstTuple, Tuple srcTuple, bool dstIsFloat, bool srcIsFloat, uint8_t sampler) { this->opcode = OP_SAMPLE; this->dst = dstTuple; this->src = srcTuple; this->dstIsFloat = dstIsFloat; this->srcIsFloat = srcIsFloat; this->samplerIdx = sampler; + this->imageIdx = imageIdx; } INLINE bool wellFormed(const Function &fn, std::string &why) const; INLINE void out(std::ostream &out, const Function &fn) const { this->outOpcode(out); out << "." << this->getDstType() << "." << this->getSrcType() - << " surface id %" << this->getSrc(fn, 0) - << " coord u %" << this->getSrc(fn, 1) - << " coord v %" << this->getSrc(fn, 2) - << " coord w %" << this->getSrc(fn, 3) + << " surface id " << this->getImageIndex() + << " coord u %" << this->getSrc(fn, 0) + << " coord v %" << this->getSrc(fn, 1) + << " coord w %" << this->getSrc(fn, 2) << " %" << this->getDst(fn, 0) << " %" << this->getDst(fn, 1) << " %" << this->getDst(fn, 2) @@ -517,6 +518,7 @@ namespace ir { Tuple src; Tuple dst; + INLINE const uint8_t getImageIndex(void) const { return this->imageIdx; } INLINE Type getSrcType(void) const { return this->srcIsFloat ? TYPE_FLOAT : TYPE_S32; } INLINE Type getDstType(void) const { return this->dstIsFloat ? TYPE_FLOAT : TYPE_U32; } INLINE const uint8_t getSamplerIndex(void) const { return this->samplerIdx; } @@ -524,8 +526,8 @@ namespace ir { uint16_t srcIsFloat:1; uint16_t dstIsFloat:1; uint16_t samplerIdx:4; - uint16_t imageIdx:8; // not used yet. - static const uint32_t srcNum = 5; + uint16_t imageIdx:8; + static const uint32_t srcNum = 4; static const uint32_t dstNum = 4; }; @@ -536,34 +538,37 @@ namespace ir { { public: - INLINE TypedWriteInstruction(Tuple srcTuple, Type srcType, Type coordType) { + INLINE TypedWriteInstruction(uint8_t imageIdx, Tuple srcTuple, Type srcType, Type coordType) { this->opcode = OP_TYPED_WRITE; this->src = srcTuple; this->coordType = coordType; this->srcType = srcType; + this->imageIdx = imageIdx; } INLINE bool wellFormed(const Function &fn, std::string &why) const; INLINE void out(std::ostream &out, const Function &fn) const { this->outOpcode(out); out << "." << this->getSrcType() - << " surface id %" << this->getSrc(fn, 0) - << " coord u %" << this->getSrc(fn, 1) - << " coord v %" << this->getSrc(fn, 2) - << " coord w %" << this->getSrc(fn, 3) + << " surface id " << this->getImageIndex() + << " coord u %" << this->getSrc(fn, 0) + << " coord v %" << this->getSrc(fn, 1) + << " coord w %" << this->getSrc(fn, 2) + << " %" << this->getSrc(fn, 3) << " %" << this->getSrc(fn, 4) << " %" << this->getSrc(fn, 5) - << " %" << this->getSrc(fn, 6) - << " %" << this->getSrc(fn, 7); + << " %" << this->getSrc(fn, 6); } Tuple src; - Type srcType; - Type coordType; + uint8_t srcType; + uint8_t coordType; + uint8_t imageIdx; - INLINE Type getSrcType(void) const { return this->srcType; } - INLINE Type getCoordType(void) const { return this->coordType; } + INLINE const uint8_t getImageIndex(void) const { return this->imageIdx; } + INLINE Type getSrcType(void) const { return (Type)this->srcType; } + INLINE Type getCoordType(void) const { return (Type)this->coordType; } // bti, u, v, w, 4 data elements - static const uint32_t srcNum = 8; + static const uint32_t srcNum = 7; Register dst[0]; //!< No dest register }; @@ -602,20 +607,20 @@ namespace ir { class ALIGNED_INSTRUCTION GetImageInfoInstruction : public BasePolicy, - public NSrcPolicy, + public NSrcPolicy, public NDstPolicy { public: GetImageInfoInstruction( int type, Register dst, - Register src, + uint8_t imageIdx, Register infoReg) { this->opcode = OP_GET_IMAGE_INFO; this->infoType = type; this->dst[0] = dst; - this->src[0] = src; - this->src[1] = infoReg; + this->src[0] = infoReg; + this->imageIdx = imageIdx; } INLINE uint32_t getInfoType(void) const { return infoType; } @@ -624,13 +629,16 @@ namespace ir { this->outOpcode(out); out << "." << this->getInfoType() << " %" << this->getDst(fn, 0) - << " surface id %" << this->getSrc(fn, 0) - << " info reg %" << this->getSrc(fn, 1); + << " surface id " << this->getImageIndex() + << " info reg %" << this->getSrc(fn, 0); } + INLINE const uint8_t getImageIndex(void) const { return imageIdx; } + uint8_t infoType; //!< Type of the requested information. - Register src[2]; //!< Surface to get info - Register dst[1]; //!< dest register to put the information. + uint8_t imageIdx; //!< surface index. + Register src[1]; //!< surface info register. + Register dst[1]; //!< dest register to put the information. static const uint32_t dstNum = 1; }; @@ -1465,9 +1473,12 @@ DECL_MEM_FN(SyncInstruction, uint32_t, getParameters(void), getParameters()) DECL_MEM_FN(SampleInstruction, Type, getSrcType(void), getSrcType()) DECL_MEM_FN(SampleInstruction, Type, getDstType(void), getDstType()) DECL_MEM_FN(SampleInstruction, const uint8_t, getSamplerIndex(void), getSamplerIndex()) +DECL_MEM_FN(SampleInstruction, const uint8_t, getImageIndex(void), getImageIndex()) DECL_MEM_FN(TypedWriteInstruction, Type, getSrcType(void), getSrcType()) DECL_MEM_FN(TypedWriteInstruction, Type, getCoordType(void), getCoordType()) +DECL_MEM_FN(TypedWriteInstruction, const uint8_t, getImageIndex(void), getImageIndex()) DECL_MEM_FN(GetImageInfoInstruction, uint32_t, getInfoType(void), getInfoType()) +DECL_MEM_FN(GetImageInfoInstruction, const uint8_t, getImageIndex(void), getImageIndex()) DECL_MEM_FN(GetSamplerInfoInstruction, const uint8_t, getSamplerIndex(void), getSamplerIndex()) #undef DECL_MEM_FN @@ -1646,16 +1657,16 @@ DECL_MEM_FN(GetSamplerInfoInstruction, const uint8_t, getSamplerIndex(void), get } // SAMPLE - Instruction SAMPLE(Tuple dst, Tuple src, bool dstIsFloat, bool srcIsFloat, uint8_t sampler) { - return internal::SampleInstruction(dst, src, dstIsFloat, srcIsFloat, sampler).convert(); + Instruction SAMPLE(uint8_t imageIndex, Tuple dst, Tuple src, bool dstIsFloat, bool srcIsFloat, uint8_t sampler) { + return internal::SampleInstruction(imageIndex, dst, src, dstIsFloat, srcIsFloat, sampler).convert(); } - Instruction TYPED_WRITE(Tuple src, Type srcType, Type coordType) { - return internal::TypedWriteInstruction(src, srcType, coordType).convert(); + Instruction TYPED_WRITE(uint8_t imageIndex, Tuple src, Type srcType, Type coordType) { + return internal::TypedWriteInstruction(imageIndex, src, srcType, coordType).convert(); } - Instruction GET_IMAGE_INFO(int infoType, Register dst, Register src, Register infoReg) { - return internal::GetImageInfoInstruction(infoType, dst, src, infoReg).convert(); + Instruction GET_IMAGE_INFO(int infoType, Register dst, uint8_t imageIndex, Register infoReg) { + return internal::GetImageInfoInstruction(infoType, dst, imageIndex, infoReg).convert(); } Instruction GET_SAMPLER_INFO(Register dst, Register samplerInfo, uint8_t samplerIdx) { diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp index ce61106..a9d9adf 100644 --- a/backend/src/ir/instruction.hpp +++ b/backend/src/ir/instruction.hpp @@ -352,6 +352,7 @@ namespace ir { }; /*! Return true if the given instruction is an instance of this class */ static bool isClassOf(const Instruction &insn); + const uint8_t getImageIndex() const; Type getSrcType(void) const; Type getCoordType(void) const; }; @@ -364,6 +365,7 @@ namespace ir { SAMPLER_BTI = 1 }; + const uint8_t getImageIndex() const; const uint8_t getSamplerIndex(void) const; Type getSrcType(void) const; Type getDstType(void) const; @@ -408,6 +410,7 @@ namespace ir { return 0; } + const uint8_t getImageIndex() const; uint32_t getInfoType() const; /*! Return true if the given instruction is an instance of this class */ static bool isClassOf(const Instruction &insn); @@ -666,11 +669,11 @@ namespace ir { /*! sync.params... (see Sync instruction) */ Instruction SYNC(uint32_t parameters); /*! typed write */ - Instruction TYPED_WRITE(Tuple src, Type srcType, Type coordType); + Instruction TYPED_WRITE(uint8_t imageIndex, Tuple src, Type srcType, Type coordType); /*! sample textures */ - Instruction SAMPLE(Tuple dst, Tuple src, bool dstIsFloat, bool srcIsFloat, uint8_t sampler); + Instruction SAMPLE(uint8_t imageIndex, Tuple dst, Tuple src, bool dstIsFloat, bool srcIsFloat, uint8_t sampler); /*! get image information , such as width/height/depth/... */ - Instruction GET_IMAGE_INFO(int infoType, Register dst, Register src, Register infoReg); + Instruction GET_IMAGE_INFO(int infoType, Register dst, uint8_t imageIndex, Register infoReg); /*! get sampler information */ Instruction GET_SAMPLER_INFO(Register dst, Register samplerInfo, uint8_t index); /*! label labelIndex */ diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp index 39df7b3..5fb6db1 100644 --- a/backend/src/llvm/llvm_gen_backend.cpp +++ b/backend/src/llvm/llvm_gen_backend.cpp @@ -2359,11 +2359,12 @@ namespace gbe case GEN_OCL_GET_IMAGE_CHANNEL_DATA_TYPE: case GEN_OCL_GET_IMAGE_CHANNEL_ORDER: { - GBE_ASSERT(AI != AE); const ir::Register surface_id = this->getRegister(*AI); ++AI; + 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; - ctx.GET_IMAGE_INFO(infoType, reg, surface_id, ctx.reg(ir::FAMILY_DWORD)); + const uint8_t surfaceID = ctx.getFunction().getImageSet()->getIdx(surfaceReg); + ctx.GET_IMAGE_INFO(infoType, reg, surfaceID, ctx.reg(ir::FAMILY_DWORD)); break; } case GEN_OCL_GET_SAMPLER_INFO: @@ -2387,7 +2388,8 @@ namespace gbe case GEN_OCL_READ_IMAGE14: case GEN_OCL_READ_IMAGE15: { - GBE_ASSERT(AI != AE); const ir::Register surface_id = this->getRegister(*AI); ++AI; + GBE_ASSERT(AI != AE); const ir::Register surfaceReg = this->getRegister(*AI); ++AI; + const uint8_t surfaceID = ctx.getFunction().getImageSet()->getIdx(surfaceReg); GBE_ASSERT(AI != AE); const uint8_t sampler = this->appendSampler(AI); ++AI; @@ -2406,7 +2408,6 @@ namespace gbe const ir::Register reg = this->getRegister(&I, elemID); dstTupleData.push_back(reg); } - srcTupleData.push_back(surface_id); srcTupleData.push_back(ucoord); srcTupleData.push_back(vcoord); srcTupleData.push_back(wcoord); @@ -2422,7 +2423,7 @@ namespace gbe #endif srcTupleData.push_back(offsetReg); const ir::Tuple dstTuple = ctx.arrayTuple(&dstTupleData[0], elemNum); - const ir::Tuple srcTuple = ctx.arrayTuple(&srcTupleData[0], 5); + const ir::Tuple srcTuple = ctx.arrayTuple(&srcTupleData[0], 4); ir::Type srcType = ir::TYPE_S32, dstType = ir::TYPE_U32; @@ -2454,7 +2455,7 @@ namespace gbe GBE_ASSERT(0); // never been here. } - ctx.SAMPLE(dstTuple, srcTuple, dstType == ir::TYPE_FLOAT, srcType == ir::TYPE_FLOAT, sampler); + ctx.SAMPLE(surfaceID, dstTuple, srcTuple, dstType == ir::TYPE_FLOAT, srcType == ir::TYPE_FLOAT, sampler); break; } case GEN_OCL_WRITE_IMAGE0: @@ -2470,7 +2471,8 @@ namespace gbe case GEN_OCL_WRITE_IMAGE14: case GEN_OCL_WRITE_IMAGE15: { - GBE_ASSERT(AI != AE); const ir::Register surface_id = this->getRegister(*AI); ++AI; + GBE_ASSERT(AI != AE); const ir::Register surfaceReg = this->getRegister(*AI); ++AI; + const uint8_t surfaceID = ctx.getFunction().getImageSet()->getIdx(surfaceReg); GBE_ASSERT(AI != AE); const ir::Register ucoord = this->getRegister(*AI); ++AI; GBE_ASSERT(AI != AE); const ir::Register vcoord = this->getRegister(*AI); ++AI; ir::Register wcoord; @@ -2481,7 +2483,6 @@ namespace gbe GBE_ASSERT(AI != AE); vector srcTupleData; - srcTupleData.push_back(surface_id); srcTupleData.push_back(ucoord); srcTupleData.push_back(vcoord); srcTupleData.push_back(wcoord); @@ -2491,7 +2492,7 @@ namespace gbe const ir::Register reg = this->getRegister(*AI, elemID); srcTupleData.push_back(reg); } - const ir::Tuple srcTuple = ctx.arrayTuple(&srcTupleData[0], 8); + const ir::Tuple srcTuple = ctx.arrayTuple(&srcTupleData[0], 7); ir::Type srcType = ir::TYPE_U32, coordType = ir::TYPE_U32; @@ -2522,7 +2523,7 @@ namespace gbe GBE_ASSERT(0); // never been here. } - ctx.TYPED_WRITE(srcTuple, srcType, coordType); + ctx.TYPED_WRITE(surfaceID, srcTuple, srcType, coordType); break; } case GEN_OCL_MUL_HI_INT: -- 2.7.4