From efa081c143d3943c824434bb1bd1c53b5e6beebe Mon Sep 17 00:00:00 2001 From: Benjamin Segovia Date: Mon, 5 Nov 2012 17:01:59 -0800 Subject: [PATCH] Removed the remaining bits of the Gen specific extensions. Much cleaner code now. --- backend/src/backend/gen_context.cpp | 135 ---------- backend/src/backend/gen_context.hpp | 4 - backend/src/backend/gen_encoder.cpp | 36 --- backend/src/backend/gen_encoder.hpp | 4 - .../src/backend/gen_insn_gen7_schedule_info.hxx | 4 - backend/src/backend/gen_insn_selection.cpp | 236 +----------------- backend/src/backend/gen_insn_selection.hxx | 4 - backend/src/ir/instruction.cpp | 274 --------------------- backend/src/ir/instruction.hpp | 77 ------ backend/src/ir/instruction.hxx | 7 - 10 files changed, 2 insertions(+), 779 deletions(-) diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp index a84eec7..5d72514 100644 --- a/backend/src/backend/gen_context.cpp +++ b/backend/src/backend/gen_context.cpp @@ -244,141 +244,6 @@ namespace gbe p->BYTE_SCATTER(src, bti, elemSize); } - void GenContext::emitRegionInstruction(const SelectionInstruction &insn) { - GBE_ASSERT(insn.dst(0).width == GEN_WIDTH_8 || - insn.dst(0).width == GEN_WIDTH_16); - const GenRegister src = ra->genReg(insn.src(0)); - const GenRegister dst = ra->genReg(insn.dst(1)); - const GenRegister final = ra->genReg(insn.dst(0)); - - // Region dimensions - const uint32_t offset = insn.extra.offset; - const uint32_t width = insn.extra.width; - const uint32_t height = simdWidth / insn.extra.width; - const uint32_t vstride = insn.extra.vstride; - const uint32_t hstride = insn.extra.hstride; - - // Region spanning in the grf - const uint32_t start = src.nr * GEN_REG_SIZE + src.subnr + offset * sizeof(int); - const uint32_t end = start + insn.srcNum * simdWidth * sizeof(int); - GBE_ASSERT(simdWidth % width == 0); - - // Right now we simply emit scalar MOVs instead of the region - p->push(); - p->curr.predicate = GEN_PREDICATE_NONE; - p->curr.execWidth = 1; - p->curr.noMask = 1; - uint32_t dstOffset = dst.nr * GEN_REG_SIZE + dst.subnr; - for (uint32_t y = 0; y < height; ++y) { - uint32_t srcOffset = start + sizeof(int) * vstride * y; - for (uint32_t x = 0; x < width; ++x, - srcOffset += sizeof(int) * hstride, - dstOffset += sizeof(int)) - { - const uint32_t dstnr = dstOffset / GEN_REG_SIZE; - const uint32_t dstsubnr = (dstOffset % GEN_REG_SIZE) / sizeof(int); - const GenRegister dstReg = GenRegister::f1grf(dstnr, dstsubnr); - if (srcOffset + sizeof(int) > end) - p->MOV(dstReg, GenRegister::immf(0.f)); - else { - GBE_ASSERT(srcOffset % sizeof(int) == 0); - const uint32_t srcnr = srcOffset / GEN_REG_SIZE; - const uint32_t srcsubnr = (srcOffset % GEN_REG_SIZE) / sizeof(int); - const GenRegister srcReg = GenRegister::f1grf(srcnr, srcsubnr); - p->MOV(dstReg, srcReg); - } - } - } - p->pop(); - p->MOV(GenRegister::retype(final, GEN_TYPE_F), GenRegister::retype(dst, GEN_TYPE_F)); - } - - void GenContext::emitRGatherInstruction(const SelectionInstruction &insn) { - const GenRegister index0 = GenRegister::retype(ra->genReg(insn.src(0)), GEN_TYPE_UW); - const GenRegister dst0 = GenRegister::retype(ra->genReg(insn.dst(0)), GEN_TYPE_F); - const GenRegister src = ra->genReg(insn.src(1)); - const uint32_t offset = src.nr * GEN_REG_SIZE + src.subnr; - p->push(); - p->curr.execWidth = 8; - p->SHL(GenRegister::addr8(0), index0, GenRegister::immuw(2)); - p->ADD(GenRegister::addr8(0), GenRegister::addr8(0), GenRegister::immuw(offset)); - p->MOV(dst0, GenRegister::indirect(GEN_TYPE_F, 0, GEN_WIDTH_8)); - p->pop(); - - if (simdWidth == 16) { - const GenRegister dst1 = GenRegister::Qn(dst0, 1); - const GenRegister index1 = GenRegister::Qn(index0, 1); - p->push(); - p->curr.execWidth = 8; - p->curr.quarterControl = GEN_COMPRESSION_Q2; - p->SHL(GenRegister::addr8(0), index1, GenRegister::immuw(2)); - p->ADD(GenRegister::addr8(0), GenRegister::addr8(0), GenRegister::immuw(offset)); - p->MOV(dst1, GenRegister::indirect(GEN_TYPE_F, 0, GEN_WIDTH_8)); - p->pop(); - } - } - - void GenContext::emitOBReadInstruction(const SelectionInstruction &insn) { - const GenRegister dst = ra->genReg(insn.dst(0)); - const GenRegister addr = ra->genReg(insn.src(0)); - const GenRegister first = GenRegister::ud1grf(addr.nr,addr.subnr/sizeof(float)); - GenRegister header; - if (simdWidth == 8) - header = GenRegister::retype(ra->genReg(insn.src(1)), GEN_TYPE_F); - else - header = GenRegister::retype(GenRegister::Qn(ra->genReg(insn.src(1)),1), GEN_TYPE_F); - - p->push(); - // Copy r0 into the header first - p->curr.execWidth = 8; - p->curr.predicate = GEN_PREDICATE_NONE; - p->curr.noMask = 1; - p->MOV(header, GenRegister::f8grf(0,0)); - - // Update the header with the current address - p->curr.execWidth = 1; - const uint32_t nr = header.nr; - const uint32_t subnr = header.subnr / sizeof(float); - p->SHR(GenRegister::ud1grf(nr, subnr+2), first, GenRegister::immud(4)); - - // Put zero in the general state base address - p->MOV(GenRegister::f1grf(nr, subnr+5), GenRegister::immf(0)); - - // Now read the data - p->OBREAD(dst, header, insn.extra.function, insn.extra.elem); - p->pop(); - } - - void GenContext::emitOBWriteInstruction(const SelectionInstruction &insn) { - const GenRegister addr = ra->genReg(insn.src(2)); - const GenRegister first = GenRegister::ud1grf(addr.nr,addr.subnr/sizeof(float)); - GenRegister header; - if (simdWidth == 8) - header = GenRegister::retype(ra->genReg(insn.src(0)), GEN_TYPE_F); - else - header = GenRegister::retype(GenRegister::Qn(ra->genReg(insn.src(0)),1), GEN_TYPE_F); - - p->push(); - // Copy r0 into the header first - p->curr.execWidth = 8; - p->curr.predicate = GEN_PREDICATE_NONE; - p->curr.noMask = 1; - p->MOV(header, GenRegister::f8grf(0,0)); - - // Update the header with the current address - p->curr.execWidth = 1; - const uint32_t nr = header.nr; - const uint32_t subnr = header.subnr / sizeof(float); - p->SHR(GenRegister::ud1grf(nr, subnr+2), first, GenRegister::immud(4)); - - // Put zero in the general state base address - p->MOV(GenRegister::f1grf(nr, subnr+5), GenRegister::immf(0)); - - // Now read the data - p->OBWRITE(header, insn.extra.function, insn.extra.elem); - p->pop(); - } - BVAR(OCL_OUTPUT_ASM, false); bool GenContext::emitCode(void) { GenKernel *genKernel = static_cast(this->kernel); diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp index 73da0a5..f6171b4 100644 --- a/backend/src/backend/gen_context.hpp +++ b/backend/src/backend/gen_context.hpp @@ -88,10 +88,6 @@ namespace gbe void emitUntypedWriteInstruction(const SelectionInstruction &insn); void emitByteGatherInstruction(const SelectionInstruction &insn); void emitByteScatterInstruction(const SelectionInstruction &insn); - void emitRegionInstruction(const SelectionInstruction &insn); - void emitRGatherInstruction(const SelectionInstruction &insn); - void emitOBReadInstruction(const SelectionInstruction &insn); - void emitOBWriteInstruction(const SelectionInstruction &insn); /*! Implements base class */ virtual Kernel *allocateKernel(void); diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp index 633d5f8..7d15646 100644 --- a/backend/src/backend/gen_encoder.cpp +++ b/backend/src/backend/gen_encoder.cpp @@ -796,42 +796,6 @@ namespace gbe return_format); } - void GenEncoder::OBREAD(GenRegister dst, GenRegister header, uint32_t bti, uint32_t size) { - GenInstruction *insn = this->next(GEN_OPCODE_SEND); - const uint32_t msg_length = 1; - const uint32_t response_length = size / 2; // Size is in owords - this->setHeader(insn); - this->setDst(insn, GenRegister::uw16grf(dst.nr, 0)); - this->setSrc0(insn, GenRegister::ud8grf(header.nr, 0)); - this->setSrc1(insn, GenRegister::immud(0)); - insn->header.execution_size = response_length == 1 ? GEN_WIDTH_8 : GEN_WIDTH_16; - setOBlockRW(this, - insn, - bti, - size, - GEN_OBLOCK_READ, - msg_length, - response_length); - } - - void GenEncoder::OBWRITE(GenRegister header, uint32_t bti, uint32_t size) { - GenInstruction *insn = this->next(GEN_OPCODE_SEND); - const uint32_t msg_length = 1 + size / 2; // Size is in owords - const uint32_t response_length = 0; - this->setHeader(insn); - this->setSrc0(insn, GenRegister::ud8grf(header.nr, 0)); - this->setSrc1(insn, GenRegister::immud(0)); - this->setDst(insn, GenRegister::retype(GenRegister::null(), GEN_TYPE_UW)); - insn->header.execution_size = msg_length == 2 ? GEN_WIDTH_8 : GEN_WIDTH_16; - setOBlockRW(this, - insn, - bti, - size, - GEN_OBLOCK_WRITE, - msg_length, - response_length); - } - void GenEncoder::EOT(uint32_t msg) { GenInstruction *insn = this->next(GEN_OPCODE_SEND); this->setDst(insn, GenRegister::retype(GenRegister::null(), GEN_TYPE_UD)); diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp index 969fa41..a2d2b8d 100644 --- a/backend/src/backend/gen_encoder.hpp +++ b/backend/src/backend/gen_encoder.hpp @@ -141,10 +141,6 @@ namespace gbe void BYTE_GATHER(GenRegister dst, GenRegister src, uint32_t bti, uint32_t elemSize); /*! Byte scatter (for unaligned bytes, shorts and ints) */ void BYTE_SCATTER(GenRegister src, uint32_t bti, uint32_t elemSize); - /*! OBlock read */ - void OBREAD(GenRegister dst, GenRegister header, uint32_t bti, uint32_t elemSize); - /*! OBlock read */ - void OBWRITE(GenRegister header, uint32_t bti, uint32_t elemSize); /*! Send instruction for the sampler */ void SAMPLE(GenRegister dest, uint32_t msg_reg_nr, diff --git a/backend/src/backend/gen_insn_gen7_schedule_info.hxx b/backend/src/backend/gen_insn_gen7_schedule_info.hxx index 2258dec..38b76b7 100644 --- a/backend/src/backend/gen_insn_gen7_schedule_info.hxx +++ b/backend/src/backend/gen_insn_gen7_schedule_info.hxx @@ -13,8 +13,4 @@ DECL_GEN7_SCHEDULE(UntypedRead, 80, 1, 1) DECL_GEN7_SCHEDULE(UntypedWrite, 80, 1, 1) DECL_GEN7_SCHEDULE(ByteGather, 80, 1, 1) DECL_GEN7_SCHEDULE(ByteScatter, 80, 1, 1) -DECL_GEN7_SCHEDULE(Region, 20, 1, 1) -DECL_GEN7_SCHEDULE(RGather, 30, 4, 2) -DECL_GEN7_SCHEDULE(OBRead, 80, 1, 1) -DECL_GEN7_SCHEDULE(OBWrite, 80, 1, 1) diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp index c429a96..f0ac4d6 100644 --- a/backend/src/backend/gen_insn_selection.cpp +++ b/backend/src/backend/gen_insn_selection.cpp @@ -102,14 +102,12 @@ namespace gbe } bool SelectionInstruction::isRead(void) const { - return this->opcode == SEL_OP_OBREAD || - this->opcode == SEL_OP_UNTYPED_READ || + return this->opcode == SEL_OP_UNTYPED_READ || this->opcode == SEL_OP_BYTE_GATHER; } bool SelectionInstruction::isWrite(void) const { - return this->opcode == SEL_OP_OBWRITE || - this->opcode == SEL_OP_UNTYPED_WRITE || + return this->opcode == SEL_OP_UNTYPED_WRITE || this->opcode == SEL_OP_BYTE_SCATTER; } @@ -396,10 +394,6 @@ namespace gbe void BYTE_GATHER(Reg dst, Reg addr, uint32_t elemSize, uint32_t bti); /*! Byte scatter (for unaligned bytes, shorts and ints) */ void BYTE_SCATTER(Reg addr, Reg src, uint32_t elemSize, uint32_t bti); - /*! Oblock read */ - void OBREAD(Reg dst, Reg addr, Reg header, uint32_t bti, uint32_t size); - /*! Oblock write */ - void OBWRITE(Reg addr, Reg value, Reg header, uint32_t bti, uint32_t size); /*! Extended math function (2 arguments) */ void MATH(Reg dst, uint32_t function, Reg src0, Reg src1); /*! Extended math function (1 argument) */ @@ -410,10 +404,6 @@ namespace gbe void ALU2(SelectionOpcode opcode, Reg dst, Reg src0, Reg src1); /*! Encode ternary instructions */ void ALU3(SelectionOpcode opcode, Reg dst, Reg src0, Reg src1, Reg src2); - /*! Encode regioning */ - void REGION(Reg dst0, Reg dst1, const GenRegister *src, uint32_t offset, uint32_t vstride, uint32_t width, uint32_t hstride, uint32_t srcNum); - /*! Encode regioning */ - void RGATHER(Reg dst, const GenRegister *src, uint32_t srcNum); /*! Use custom allocators */ GBE_CLASS(Opaque); friend class SelectionBlock; @@ -731,74 +721,6 @@ namespace gbe insn->src(2) = src2; } - void Selection::Opaque::REGION(Reg dst0, Reg dst1, const GenRegister *src, - uint32_t offset, uint32_t vstride, - uint32_t width, uint32_t hstride, - uint32_t srcNum) - { - SelectionInstruction *insn = this->appendInsn(SEL_OP_REGION, 2, srcNum); - SelectionVector *vector = this->appendVector(); - - // Instruction to encode - insn->dst(0) = dst0; - insn->dst(1) = dst1; - GBE_ASSERT(srcNum <= SelectionInstruction::MAX_SRC_NUM); - for (uint32_t srcID = 0; srcID < srcNum; ++srcID) - insn->src(srcID) = src[srcID]; - insn->extra.vstride = vstride; - insn->extra.width = width; - insn->extra.offset = offset; - insn->extra.hstride = hstride; - - // Regioning requires contiguous allocation for the sources - vector->regNum = srcNum; - vector->reg = &insn->src(0); - vector->isSrc = 1; - } - - void Selection::Opaque::RGATHER(Reg dst, const GenRegister *src, uint32_t srcNum) - { - SelectionInstruction *insn = this->appendInsn(SEL_OP_RGATHER, 1, srcNum); - SelectionVector *vector = this->appendVector(); - - // Instruction to encode - insn->dst(0) = dst; - GBE_ASSERT(srcNum <= SelectionInstruction::MAX_SRC_NUM); - for (uint32_t srcID = 0; srcID < srcNum; ++srcID) - insn->src(srcID) = src[srcID]; - - // Regioning requires contiguous allocation for the sources - vector->regNum = srcNum; - vector->reg = &insn->src(0); - vector->isSrc = 1; - } - - void Selection::Opaque::OBREAD(Reg dst, Reg addr, Reg header, uint32_t bti, uint32_t size) { - SelectionInstruction *insn = this->appendInsn(SEL_OP_OBREAD, 1, 2); - insn->dst(0) = dst; - insn->src(0) = addr; - insn->src(1) = header; - insn->extra.function = bti; - insn->extra.elem = size / sizeof(int[4]); // number of owords - } - - void Selection::Opaque::OBWRITE(Reg addr, Reg value, Reg header, uint32_t bti, uint32_t size) { - SelectionInstruction *insn = this->appendInsn(SEL_OP_OBWRITE, 0, 3); - SelectionVector *vector = this->appendVector(); - insn->opcode = SEL_OP_OBWRITE; - insn->src(0) = header; - insn->src(1) = value; - insn->src(2) = addr; - insn->state = this->curr; - insn->extra.function = bti; - insn->extra.elem = size / sizeof(int[4]); // number of owords - - // We need to put the header and the data together - vector->regNum = 2; - vector->reg = &insn->src(0); - vector->isSrc = 1; - } - // Boiler plate to initialize the selection library at c++ pre-main static SelectionLibrary *selLib = NULL; static void destroySelectionLibrary(void) { GBE_DELETE(selLib); } @@ -1743,155 +1665,6 @@ namespace gbe DECL_CTOR(LabelInstruction, 1, 1); }; - /*! Region instruction pattern */ - DECL_PATTERN(RegionInstruction) - { - INLINE bool emitOne(Selection::Opaque &sel, const ir::RegionInstruction &insn) const - { - using namespace ir; - - // Two destinations: one is the real destination, one is a temporary - GenRegister dst0 = sel.selReg(insn.getDst(0)), dst1; - if (sel.ctx.getSimdWidth() == 8) - dst1 = GenRegister::ud8grf(sel.reg(FAMILY_DWORD)); - else - dst1 = GenRegister::ud16grf(sel.reg(FAMILY_DWORD)); - - // Get all the sources - GenRegister src[SelectionInstruction::MAX_SRC_NUM]; - const uint32_t srcNum = insn.getSrcNum(); - GBE_ASSERT(srcNum <= SelectionInstruction::MAX_SRC_NUM); - for (uint32_t srcID = 0; srcID < insn.getSrcNum(); ++srcID) - src[srcID] = sel.selReg(insn.getSrc(srcID)); - - // Get the region parameters - const uint32_t offset = insn.getOffset(); - const uint32_t vstride = insn.getVStride(); - const uint32_t width = insn.getWidth(); - const uint32_t hstride = insn.getHStride(); - sel.REGION(dst0, dst1, src, offset, vstride, width, hstride, srcNum); - return true; - } - DECL_CTOR(RegionInstruction, 1, 1); - }; - - /*! Vote instruction pattern */ - DECL_PATTERN(VoteInstruction) - { - INLINE bool emitOne(Selection::Opaque &sel, const ir::VoteInstruction &insn) const - { - using namespace ir; - const uint32_t simdWidth = sel.ctx.getSimdWidth(); - const GenRegister dst = sel.selReg(insn.getDst(0), TYPE_U16); - const GenRegister src = sel.selReg(insn.getSrc(0), TYPE_U16); - - // Limit the vote to the active lanes. Use the same compare as for f0.0 - sel.push(); - const LabelIndex label = insn.getParent()->getLabelIndex(); - const GenRegister blockip = sel.selReg(ocl::blockip, TYPE_U16); - const GenRegister labelReg = GenRegister::immuw(label); - sel.curr.predicate = GEN_PREDICATE_NONE; - sel.curr.flag = 0; - sel.curr.subFlag = 1; - sel.CMP(GEN_CONDITIONAL_LE, blockip, labelReg); - sel.pop(); - - // Emit the compare instruction to get the flag register - sel.push(); - const VotePredicate vote = insn.getVotePredicate(); - const uint32_t genCmp = vote == VOTE_ANY ? GEN_CONDITIONAL_NEQ : GEN_CONDITIONAL_EQ; - sel.curr.flag = 0; - sel.curr.subFlag = 1; - sel.CMP(genCmp, src, GenRegister::immuw(0)); - sel.pop(); - - // Broadcast the result to the destination - if (vote == VOTE_ANY) - sel.MOV(dst, GenRegister::flag(0,1)); - else { - const GenRegister tmp = sel.selReg(sel.reg(FAMILY_WORD), TYPE_U16); - sel.push(); - // Set all lanes of tmp to zero - sel.curr.predicate = GEN_PREDICATE_NONE; - sel.MOV(tmp, GenRegister::immuw(0)); - - // Compute the short values with no mask - sel.curr.flag = 0; - sel.curr.subFlag = 1; - sel.curr.inversePredicate = 1; - sel.curr.predicate = simdWidth == 8 ? - GEN_PREDICATE_ALIGN1_ANY8H : - GEN_PREDICATE_ALIGN1_ANY16H; - sel.MOV(tmp, GenRegister::immuw(1)); - sel.pop(); - - // Update the destination with the proper mask - sel.MOV(dst, tmp); - } - return true; - } - - DECL_CTOR(VoteInstruction, 1, 1); - }; - - /*! Register file gather instruction pattern */ - DECL_PATTERN(RGatherInstruction) - { - INLINE bool emitOne(Selection::Opaque &sel, const ir::RGatherInstruction &insn) const - { - using namespace ir; - // Two destinations: one is the real destination, one is a temporary - const GenRegister dst = sel.selReg(insn.getDst(0)), dst1; - - // Get all the sources - GenRegister src[SelectionInstruction::MAX_SRC_NUM]; - const uint32_t srcNum = insn.getSrcNum(); - GBE_ASSERT(srcNum <= SelectionInstruction::MAX_SRC_NUM); - for (uint32_t srcID = 0; srcID < insn.getSrcNum(); ++srcID) - src[srcID] = sel.selReg(insn.getSrc(srcID)); - - // Get the region parameters - sel.RGATHER(dst, src, srcNum); - return true; - } - - DECL_CTOR(RGatherInstruction, 1, 1); - }; - - /*! OBlock read instruction pattern */ - DECL_PATTERN(OBReadInstruction) - { - INLINE bool emitOne(Selection::Opaque &sel, const ir::OBReadInstruction &insn) const - { - using namespace ir; - const GenRegister header = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32); - const GenRegister addr = sel.selReg(insn.getAddress(), TYPE_U32); - const GenRegister value = sel.selReg(insn.getValue(), TYPE_U32); - const uint32_t simdWidth = sel.ctx.getSimdWidth(); - sel.OBREAD(value, addr, header, 0xff, simdWidth * sizeof(int)); - return true; - } - - DECL_CTOR(OBReadInstruction, 1, 1); - }; - - /*! OBlock write instruction pattern */ - DECL_PATTERN(OBWriteInstruction) - { - INLINE bool emitOne(Selection::Opaque &sel, const ir::OBWriteInstruction &insn) const - { - using namespace ir; - const GenRegister header = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32); - const GenRegister addr = sel.selReg(insn.getAddress(), TYPE_U32); - const GenRegister value = sel.selReg(insn.getValue(), TYPE_U32); - const uint32_t simdWidth = sel.ctx.getSimdWidth(); - sel.OBWRITE(addr, value, header, 0xff, simdWidth * sizeof(int)); - return true; - } - - DECL_CTOR(OBWriteInstruction, 1, 1); - }; - /*! Branch instruction pattern */ DECL_PATTERN(BranchInstruction) { @@ -2056,11 +1829,6 @@ namespace gbe this->insert(); this->insert(); this->insert(); - this->insert(); - this->insert(); - this->insert(); - this->insert(); - this->insert(); this->insert(); this->insert(); this->insert(); diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx index 8dcf2b5..45e7ef2 100644 --- a/backend/src/backend/gen_insn_selection.hxx +++ b/backend/src/backend/gen_insn_selection.hxx @@ -30,8 +30,4 @@ DECL_SELECTION_IR(UNTYPED_READ, UntypedReadInstruction) DECL_SELECTION_IR(UNTYPED_WRITE, UntypedWriteInstruction) DECL_SELECTION_IR(BYTE_GATHER, ByteGatherInstruction) DECL_SELECTION_IR(BYTE_SCATTER, ByteScatterInstruction) -DECL_SELECTION_IR(REGION, RegionInstruction) -DECL_SELECTION_IR(RGATHER, RGatherInstruction) -DECL_SELECTION_IR(OBREAD, OBReadInstruction) -DECL_SELECTION_IR(OBWRITE, OBWriteInstruction) diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp index e1c75e5..e564ac4 100644 --- a/backend/src/ir/instruction.cpp +++ b/backend/src/ir/instruction.cpp @@ -490,117 +490,6 @@ namespace ir { Register dst[], src[]; }; - class ALIGNED_INSTRUCTION RegionInstruction : - public BasePolicy, - public NDstPolicy, - public TupleSrcPolicy - { - public: - RegionInstruction(Register dst, - Tuple src, - uint32_t srcNum, - uint32_t offset, - uint32_t vstride, - uint32_t width, - uint32_t hstride) - { - this->opcode = OP_REGION; - this->dst[0] = dst; - this->src = src; - this->srcNum = srcNum; - this->offset = offset; - this->vstride = vstride; - this->width = width; - this->hstride = hstride; - } - INLINE uint32_t getOffset(void) const { return this->offset; } - INLINE uint32_t getVStride(void) const { return this->vstride; } - INLINE uint32_t getWidth(void) const { return this->width; } - INLINE uint32_t getHStride(void) const { return this->hstride; } - INLINE bool wellFormed(const Function &fn, std::string &whyNot) const; - INLINE void out(std::ostream &out, const Function &fn) const; - uint8_t srcNum:4; //!< Number of sources in the tuple - uint8_t width:4; //!< width (1,2,4 or 8) - Register dst[1]; //!< Dst is the register index - Tuple src; //!< Contiguous registers we gather data from - uint16_t vstride:5; //!< vertical stride (0,1,2,4,8 or 16) - uint16_t hstride:5; //!< horizontal stride (0,1,2,4,8 or 16) - uint16_t offset:5; //!< offset (0 to 7) - }; - - class ALIGNED_INSTRUCTION VoteInstruction : - public BasePolicy, - public NDstPolicy, - public NSrcPolicy - { - public: - VoteInstruction(Register dst, Register src, VotePredicate pred) { - this->opcode = OP_VOTE; - this->dst[0] = dst; - this->src[0] = src; - this->pred = pred; - } - INLINE VotePredicate getVotePredicate(void) const { return this->pred; } - INLINE bool wellFormed(const Function &fn, std::string &whyNot) const; - INLINE void out(std::ostream &out, const Function &fn) const; - Register dst[1]; //!< Destination boolean - Register src[1]; //!< Source boolean (n lanes internally) - VotePredicate pred; //!< Operation to apply on the lanes - }; - - class ALIGNED_INSTRUCTION RGatherInstruction : - public BasePolicy, - public NDstPolicy, - public TupleSrcPolicy - { - public: - RGatherInstruction(Register dst, Tuple src, uint32_t srcNum) { - this->opcode = OP_RGATHER; - this->dst[0] = dst; - this->src = src; - this->srcNum = srcNum; - } - INLINE bool wellFormed(const Function &fn, std::string &whyNot) const; - INLINE void out(std::ostream &out, const Function &fn) const; - uint8_t srcNum:4; //!< Number of sources in the tuple - Register dst[1]; //!< Dst is the register index - Tuple src; //!< Contiguous registers we gather data from - }; - - class ALIGNED_INSTRUCTION OBReadInstruction : - public BasePolicy, - public NDstPolicy, - public NSrcPolicy - { - public: - OBReadInstruction(Register value, Register address) { - this->opcode = OP_OBREAD; - this->dst[0] = value; - this->src[0] = address; - } - INLINE bool wellFormed(const Function &fn, std::string &whyNot) const; - INLINE void out(std::ostream &out, const Function &fn) const; - Register dst[1]; //!< Value to get from memory - Register src[1]; //!< Address to read - }; - - class ALIGNED_INSTRUCTION OBWriteInstruction : - public BasePolicy, - public NDstPolicy, - public NSrcPolicy - { - public: - OBWriteInstruction(Register address, Register value) { - this->opcode = OP_OBWRITE; - this->src[0] = address; - this->src[1] = value; - } - INLINE bool wellFormed(const Function &fn, std::string &whyNot) const; - INLINE void out(std::ostream &out, const Function &fn) const; - Register src[2]; // src[0] == address, src[1] == value - Register dst[0]; //!< No destination - }; - #undef ALIGNED_INSTRUCTION ///////////////////////////////////////////////////////////////////////// @@ -904,82 +793,6 @@ namespace ir { return true; } - // Stride is 1,2,4,8 offset goes from 0 to 15 and registers must be dwords - INLINE bool RegionInstruction::wellFormed(const Function &fn, std::string &whyNot) const - { - if (UNLIKELY(vstride != 0 && vstride != 1 && vstride != 2 && vstride != 4 && vstride != 8 && vstride != 16)) { - whyNot = "Invalid vertical stride (must be 0, 1, 2, 4 or 8)"; - return false; - } - if (UNLIKELY(hstride != 0 && hstride != 1 && hstride != 2 && hstride != 4 && hstride != 8 && hstride != 16)) { - whyNot = "Invalid horizontal stride (must be 0, 1, 2, 4 or 8)"; - return false; - } - if (UNLIKELY(width != 0 && width != 1 && width != 2 && width != 4 && width != 8)) { - whyNot = "Invalid width (must be 1, 2, 4 or 8)"; - return false; - } - if (UNLIKELY(offset > 7)) { - whyNot = "Invalid offset (must be smaller than 8)"; - return false; - } - if (UNLIKELY(checkRegisterData(FAMILY_DWORD, dst[0], fn, whyNot) == false)) - return false; - for (uint32_t srcID = 0; srcID < srcNum; ++srcID) { - const Register regID = fn.getRegister(src, srcID); - if (UNLIKELY(checkRegisterData(FAMILY_DWORD, regID, fn, whyNot) == false)) - return false; - } - return true; - } - - // Boolean values for both source and destination - INLINE bool VoteInstruction::wellFormed(const Function &fn, std::string &whyNot) const - { - if (UNLIKELY(checkRegisterData(FAMILY_WORD, dst[0], fn, whyNot) == false)) - return false; - if (UNLIKELY(checkRegisterData(FAMILY_WORD, src[0], fn, whyNot) == false)) - return false; - return true; - } - - // Indices are always int16 and the rest is 32 bit integers - INLINE bool RGatherInstruction::wellFormed(const Function &fn, std::string &whyNot) const - { - if (UNLIKELY(checkRegisterData(FAMILY_DWORD, dst[0], fn, whyNot) == false)) - return false; - if (UNLIKELY(checkRegisterData(FAMILY_WORD, fn.getRegister(src, 0), fn, whyNot) == false)) - return false; - for (uint32_t srcID = 1; srcID < srcNum; ++srcID) { - const Register regID = fn.getRegister(src, srcID); - if (UNLIKELY(checkRegisterData(FAMILY_DWORD, regID, fn, whyNot) == false)) - return false; - } - return true; - } - - // Source is an address. Destination is a 32 bit integer - INLINE bool OBReadInstruction::wellFormed(const Function &fn, std::string &whyNot) const - { - const RegisterFamily ptrFamily = fn.getPointerFamily(); - if (UNLIKELY(checkRegisterData(ptrFamily, src[0], fn, whyNot) == false)) - return false; - if (UNLIKELY(checkRegisterData(FAMILY_DWORD, dst[0], fn, whyNot) == false)) - return false; - return true; - } - - // First source is the address. Second source is the value to write - INLINE bool OBWriteInstruction::wellFormed(const Function &fn, std::string &whyNot) const - { - const RegisterFamily ptrFamily = fn.getPointerFamily(); - if (UNLIKELY(checkRegisterData(ptrFamily, src[0], fn, whyNot) == false)) - return false; - if (UNLIKELY(checkRegisterData(FAMILY_DWORD, src[1], fn, whyNot) == false)) - return false; - return true; - } - #undef CHECK_TYPE ///////////////////////////////////////////////////////////////////////// @@ -1058,42 +871,6 @@ namespace ir { fn.outImmediate(out, immediateIndex); } - INLINE void RegionInstruction::out(std::ostream &out, const Function &fn) const { - this->outOpcode(out); - out << "<" << uint32_t(vstride) << ";" - << uint32_t(width) << "," << uint32_t(hstride) - << ">." << uint32_t(offset) << " "; - out << "%" << this->getDst(fn, 0) << " "; - for (uint32_t i = 0; i < this->getSrcNum(); ++i) - out << "%" << this->getSrc(fn, i) << (i != (srcNum-1u) ? " " : ""); - } - - INLINE void VoteInstruction::out(std::ostream &out, const Function &fn) const { - this->outOpcode(out); - out << "." << (this->getVotePredicate() == VOTE_ALL ? "all" : "any") - << " %" << this->getDst(fn, 0) - << " %" << this->getSrc(fn, 0); - } - - INLINE void RGatherInstruction::out(std::ostream &out, const Function &fn) const { - this->outOpcode(out); - out << " %" << this->getDst(fn, 0); - for (uint32_t i = 0; i < this->getSrcNum(); ++i) - out << " %" << this->getSrc(fn, i); - } - - INLINE void OBReadInstruction::out(std::ostream &out, const Function &fn) const { - this->outOpcode(out); - out << " %" << this->getDst(fn, 0); - out << " %" << this->getSrc(fn, 0); - } - - INLINE void OBWriteInstruction::out(std::ostream &out, const Function &fn) const { - this->outOpcode(out); - out << " %" << this->getSrc(fn, 0); - out << " %" << this->getSrc(fn, 1); - } - } /* namespace internal */ std::ostream &operator<< (std::ostream &out, AddressSpace addrSpace) { @@ -1201,26 +978,6 @@ START_INTROSPECTION(LabelInstruction) #include "ir/instruction.hxx" END_INTROSPECTION(LabelInstruction) -START_INTROSPECTION(RegionInstruction) -#include "ir/instruction.hxx" -END_INTROSPECTION(RegionInstruction) - -START_INTROSPECTION(VoteInstruction) -#include "ir/instruction.hxx" -END_INTROSPECTION(VoteInstruction) - -START_INTROSPECTION(RGatherInstruction) -#include "ir/instruction.hxx" -END_INTROSPECTION(RGatherInstruction) - -START_INTROSPECTION(OBReadInstruction) -#include "ir/instruction.hxx" -END_INTROSPECTION(OBReadInstruction) - -START_INTROSPECTION(OBWriteInstruction) -#include "ir/instruction.hxx" -END_INTROSPECTION(OBWriteInstruction) - #undef END_INTROSPECTION #undef START_INTROSPECTION #undef DECL_INSN @@ -1367,7 +1124,6 @@ END_FUNCTION(Instruction, Register) bool Instruction::hasSideEffect(void) const { return opcode == OP_STORE || - opcode == OP_OBWRITE || opcode == OP_TYPED_WRITE || opcode == OP_FENCE; } @@ -1397,11 +1153,6 @@ DECL_MEM_FN(LoadImmInstruction, Type, getType(void), getType()) DECL_MEM_FN(LabelInstruction, LabelIndex, getLabelIndex(void), getLabelIndex()) DECL_MEM_FN(BranchInstruction, bool, isPredicated(void), isPredicated()) DECL_MEM_FN(BranchInstruction, LabelIndex, getLabelIndex(void), getLabelIndex()) -DECL_MEM_FN(RegionInstruction, uint32_t, getOffset(void), getOffset()) -DECL_MEM_FN(RegionInstruction, uint32_t, getVStride(void), getVStride()) -DECL_MEM_FN(RegionInstruction, uint32_t, getWidth(void), getWidth()) -DECL_MEM_FN(RegionInstruction, uint32_t, getHStride(void), getHStride()) -DECL_MEM_FN(VoteInstruction, VotePredicate, getVotePredicate(void), getVotePredicate()) #undef DECL_MEM_FN @@ -1537,31 +1288,6 @@ DECL_MEM_FN(VoteInstruction, VotePredicate, getVotePredicate(void), getVotePredi return internal::LabelInstruction(labelIndex).convert(); } - // REGION - Instruction REGION(uint32_t offset, uint32_t vstride, uint32_t width, uint32_t hstride, Register dst, Tuple src, uint32_t srcNum) { - return internal::RegionInstruction(dst, src, srcNum, offset, vstride, width, hstride).convert(); - } - - // VOTE - Instruction VOTE(VotePredicate pred, Register dst, Register src) { - return internal::VoteInstruction(dst, src, pred).convert(); - } - - // RGATHER - Instruction RGATHER(Register dst, Tuple src, uint32_t srcNum) { - return internal::RGatherInstruction(dst, src, srcNum).convert(); - } - - // OBREAD - Instruction OBREAD(Register dst, Register address) { - return internal::OBReadInstruction(dst, address).convert(); - } - - // OBWRITE - Instruction OBWRITE(Register address, Register value) { - return internal::OBWriteInstruction(address, value).convert(); - } - std::ostream &operator<< (std::ostream &out, const Instruction &insn) { const Function &fn = insn.getFunction(); switch (insn.getOpcode()) { diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp index c1b8323..dcde8dc 100644 --- a/backend/src/ir/instruction.hpp +++ b/backend/src/ir/instruction.hpp @@ -365,73 +365,6 @@ namespace ir { static bool isClassOf(const Instruction &insn); }; - /*! Register region instructions are specific to OpenCL Gen and allow to - * manipulate the register file and to do cross lane shuffles (Gen extension) - */ - class RegionInstruction : public Instruction { - public: - /*! Return the offset index (0..7) for the strided load*/ - uint32_t getOffset(void) const; - /*! Return the vertical stride (0,1,2,4,8) */ - uint32_t getVStride(void) const; - /*! Return the width (0,1,2,4,8) */ - uint32_t getWidth(void) const; - /*! Return the horizontal stride (0,1,2,4,8) */ - uint32_t getHStride(void) const; - /*! Return true if the given instruction is an instance of this class */ - static bool isClassOf(const Instruction &insn); - }; - - /*! Vote instruction that operates accross lanes from the same hardware - * thread (Gen extension) - */ - class VoteInstruction : public Instruction { - public: - /*! Return the vote predicate */ - VotePredicate getVotePredicate(void) const; - /*! Return true if the given instruction is an instance of this class */ - static bool isClassOf(const Instruction &insn); - }; - - /*! Gather from register file instruction. Similar to register region but with - * indirect addressing (Gen extension) - */ - class RGatherInstruction : public Instruction { - public: - /*!< Source ID for the indices */ - static const uint32_t indexID = 0; - /*! Get the indices for the gather */ - INLINE Register getIndices(void) const { return this->getSrc(indexID); } - /*! Return true if the given instruction is an instance of this class */ - static bool isClassOf(const Instruction &insn); - }; - - /*! OBlock read. Only the first lane is considered for the address - * (Gen extension) - */ - class OBReadInstruction : public Instruction { - public: - /*! Get the address register */ - INLINE Register getAddress(void) const { return this->getSrc(0); } - /*! Get the value (i.e. destination here) */ - INLINE Register getValue(void) const { return this->getDst(0); } - /*! Return true if the given instruction is an instance of this class */ - static bool isClassOf(const Instruction &insn); - }; - - /*! OBlock write. Only the first lane is considered for the address - * (Gen extension) - */ - class OBWriteInstruction : public Instruction { - public: - /*! Get the address register */ - INLINE Register getAddress(void) const { return this->getSrc(0); } - /*! Get the value to write */ - INLINE Register getValue(void) const { return this->getSrc(1); } - /*! Return true if the given instruction is an instance of this class */ - static bool isClassOf(const Instruction &insn); - }; - /*! Specialize the instruction. Also performs typechecking first based on the * opcode. Crashes if it fails */ @@ -570,16 +503,6 @@ namespace ir { Instruction FENCE(AddressSpace space); /*! label labelIndex */ Instruction LABEL(LabelIndex labelIndex); - /*! region.offset.stride dst {src1,...,src_srcNum} */ - Instruction REGION(uint32_t offset, uint32_t vstride, uint32_t width, uint32_t hstride, Register dst, Tuple src, uint32_t srcNum); - /*! vote.predcate dst src */ - Instruction VOTE(VotePredicate predicate, Register dst, Register src); - /*! rgather dst index {src...} (tuple contains index and sources) */ - Instruction RGATHER(Register dst, Tuple tuple, uint32_t srcNum); - /*! obread dst address */ - Instruction OBREAD(Register dst, Register address); - /*! obwrite address data */ - Instruction OBWRITE(Register address, Register value); } /* namespace ir */ } /* namespace gbe */ diff --git a/backend/src/ir/instruction.hxx b/backend/src/ir/instruction.hxx index 4f154b0..05e2794 100644 --- a/backend/src/ir/instruction.hxx +++ b/backend/src/ir/instruction.hxx @@ -70,10 +70,3 @@ DECL_INSN(SAMPLE, SampleInstruction) DECL_INSN(FENCE, FenceInstruction) DECL_INSN(LABEL, LabelInstruction) -// OpenCL Gen extensions -DECL_INSN(REGION, RegionInstruction) -DECL_INSN(VOTE, VoteInstruction) -DECL_INSN(RGATHER, RGatherInstruction) -DECL_INSN(OBREAD, OBReadInstruction) -DECL_INSN(OBWRITE, OBWriteInstruction) - -- 2.7.4