From: Junyan He <junyan...@linux.intel.com> Signed-off-by: Junyan He <junyan...@linux.intel.com> --- backend/src/ir/instruction.cpp | 160 ++++++++++++++++++++++++++++++++++++++++ backend/src/ir/instruction.hpp | 28 +++++++ backend/src/ir/instruction.hxx | 1 + 3 files changed, 189 insertions(+)
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp index 6ed0b89..33be93a 100644 --- a/backend/src/ir/instruction.cpp +++ b/backend/src/ir/instruction.cpp @@ -949,6 +949,36 @@ namespace ir { Register dst[0], src[0]; }; + class ALIGNED_INSTRUCTION WorkGroupInstruction : + public BasePolicy, + public TupleSrcPolicy<WorkGroupInstruction>, + public NDstPolicy<WorkGroupInstruction, 1> + { + public: + INLINE WorkGroupInstruction(WorkGroupOps opcode, uint32_t slmAddr, Register dst, + Tuple srcTuple, uint8_t srcNum, Type type) { + this->opcode = OP_WORKGROUP; + this->workGroupOp = opcode; + this->type = type; + this->dst[0] = dst; + this->src = srcTuple; + this->srcNum = srcNum; + this->slmAddr = slmAddr; + } + INLINE Type getType(void) const { return this->type; } + INLINE bool wellFormed(const Function &fn, std::string &whyNot) const; + INLINE void out(std::ostream &out, const Function &fn) const; + INLINE WorkGroupOps getWorkGroupOpcode(void) const { return this->workGroupOp; } + uint32_t getSlmAddr(void) const { return this->slmAddr; } + + WorkGroupOps workGroupOp:5; + uint32_t srcNum:3; //!< Source Number + uint32_t slmAddr:24; //!< Thread Map in SLM. + Type type; //!< Type of the instruction + Tuple src; + Register dst[1]; + }; + #undef ALIGNED_INSTRUCTION ///////////////////////////////////////////////////////////////////////// @@ -1378,6 +1408,54 @@ namespace ir { return true; } + INLINE bool WorkGroupInstruction::wellFormed(const Function &fn, std::string &whyNot) const { + const RegisterFamily family = getFamily(this->type); + if (UNLIKELY(checkSpecialRegForWrite(dst[0], fn, whyNot) == false)) + return false; + if (UNLIKELY(checkRegisterData(family, dst[0], fn, whyNot) == false)) + return false; + const Register src0 = fn.getRegister(src, 0); + if (UNLIKELY(checkRegisterData(family, src0, fn, whyNot) == false)) + return false; + + switch (this->workGroupOp) { + case WORKGROUP_OP_ANY: + case WORKGROUP_OP_ALL: + case WORKGROUP_OP_REDUCE_ADD: + case WORKGROUP_OP_REDUCE_MIN: + case WORKGROUP_OP_REDUCE_MAX: + case WORKGROUP_OP_INCLUSIVE_ADD: + case WORKGROUP_OP_INCLUSIVE_MIN: + case WORKGROUP_OP_INCLUSIVE_MAX: + case WORKGROUP_OP_EXCLUSIVE_ADD: + case WORKGROUP_OP_EXCLUSIVE_MIN: + case WORKGROUP_OP_EXCLUSIVE_MAX: + if (this->srcNum != 1) { + whyNot = "Wrong number of source."; + return false; + } + break; + case WORKGROUP_OP_BROADCAST: + if (this->srcNum <= 1) { + whyNot = "Wrong number of source."; + return false; + } else { + const RegisterFamily fam = FAMILY_DWORD; + for (uint32_t srcID = 1; srcID < this->srcNum; ++srcID) { + const Register regID = fn.getRegister(src, srcID); + if (UNLIKELY(checkRegisterData(fam, regID, fn, whyNot) == false)) + return false; + } + } + break; + default: + whyNot = "No such work group function."; + return false; + } + + return true; + } + #undef CHECK_TYPE ///////////////////////////////////////////////////////////////////////// @@ -1531,7 +1609,78 @@ namespace ir { out << "." << syncStr[field]; } + INLINE void WorkGroupInstruction::out(std::ostream &out, const Function &fn) const { + this->outOpcode(out); + switch (this->workGroupOp) { + case WORKGROUP_OP_ANY: + out << "_" << "ANY"; + break; + case WORKGROUP_OP_ALL: + out << "_" << "ALL"; + break; + case WORKGROUP_OP_REDUCE_ADD: + out << "_" << "REDUCE_ADD"; + break; + case WORKGROUP_OP_REDUCE_MIN: + out << "_" << "REDUCE_MIN"; + break; + case WORKGROUP_OP_REDUCE_MAX: + out << "_" << "REDUCE_MAX"; + break; + case WORKGROUP_OP_INCLUSIVE_ADD: + out << "_" << "INCLUSIVE_ADD"; + break; + case WORKGROUP_OP_INCLUSIVE_MIN: + out << "_" << "INCLUSIVE_MIN"; + break; + case WORKGROUP_OP_INCLUSIVE_MAX: + out << "_" << "INCLUSIVE_MAX"; + break; + case WORKGROUP_OP_EXCLUSIVE_ADD: + out << "_" << "EXCLUSIVE_ADD"; + break; + case WORKGROUP_OP_EXCLUSIVE_MIN: + out << "_" << "EXCLUSIVE_MIN"; + break; + case WORKGROUP_OP_EXCLUSIVE_MAX: + out << "_" << "EXCLUSIVE_MAX"; + break; + case WORKGROUP_OP_BROADCAST: + out << "_" << "BROADCAST"; + break; + default: + GBE_ASSERT(0); + } + + out << " %" << this->getDst(fn, 0); + out << " %" << this->getSrc(fn, 0); + + if (this->workGroupOp == WORKGROUP_OP_BROADCAST) { + do { + int localN = srcNum - 1; + GBE_ASSERT(localN); + out << " Local X:"; + out << " %" << this->getSrc(fn, 1); + localN--; + if (!localN) + break; + + out << " Local Y:"; + out << " %" << this->getSrc(fn, 2); + localN--; + if (!localN) + break; + + out << " Local Z:"; + out << " %" << this->getSrc(fn, 3); + localN--; + GBE_ASSERT(!localN); + } while(0); + } + + out << "TheadID Map at SLM: " << this->slmAddr; + } } /* namespace internal */ std::ostream &operator<< (std::ostream &out, AddressSpace addrSpace) { @@ -1684,6 +1833,10 @@ START_INTROSPECTION(VmeInstruction) #include "ir/instruction.hxx" END_INTROSPECTION(VmeInstruction) +START_INTROSPECTION(WorkGroupInstruction) +#include "ir/instruction.hxx" +END_INTROSPECTION(WorkGroupInstruction) + #undef END_INTROSPECTION #undef START_INTROSPECTION #undef DECL_INSN @@ -1889,6 +2042,9 @@ DECL_MEM_FN(CalcTimestampInstruction, uint32_t, getPointNum(void), getPointNum() DECL_MEM_FN(CalcTimestampInstruction, uint32_t, getTimestamptType(void), getTimestamptType()) DECL_MEM_FN(StoreProfilingInstruction, uint32_t, getProfilingType(void), getProfilingType()) DECL_MEM_FN(StoreProfilingInstruction, uint32_t, getBTI(void), getBTI()) +DECL_MEM_FN(WorkGroupInstruction, Type, getType(void), getType()) +DECL_MEM_FN(WorkGroupInstruction, WorkGroupOps, getWorkGroupOpcode(void), getWorkGroupOpcode()) +DECL_MEM_FN(WorkGroupInstruction, uint32_t, getSlmAddr(void), getSlmAddr()) #undef DECL_MEM_FN @@ -2174,6 +2330,10 @@ DECL_MEM_FN(MemInstruction, void, setBtiReg(Register reg), setBtiReg(reg)) return internal::StoreProfilingInstruction(bti, profilingType).convert(); } + Instruction WORKGROUP(WorkGroupOps opcode, uint32_t slmAddr, Register dst, Tuple srcTuple, uint8_t srcNum, Type type) { + return internal::WorkGroupInstruction(opcode, slmAddr, dst, srcTuple, srcNum, type).convert(); + } + std::ostream &operator<< (std::ostream &out, const Instruction &insn) { const Function &fn = insn.getFunction(); const BasicBlock *bb = insn.getParent(); diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp index 7862bbf..3a5a681 100644 --- a/backend/src/ir/instruction.hpp +++ b/backend/src/ir/instruction.hpp @@ -89,6 +89,22 @@ namespace ir { ATOMIC_OP_INVALID }; + enum WorkGroupOps { + WORKGROUP_OP_ANY = 1, + WORKGROUP_OP_ALL = 2, + WORKGROUP_OP_BROADCAST = 3, + WORKGROUP_OP_REDUCE_ADD = 4, + WORKGROUP_OP_REDUCE_MIN = 5, + WORKGROUP_OP_REDUCE_MAX = 6, + WORKGROUP_OP_INCLUSIVE_ADD = 7, + WORKGROUP_OP_INCLUSIVE_MIN = 8, + WORKGROUP_OP_INCLUSIVE_MAX = 9, + WORKGROUP_OP_EXCLUSIVE_ADD = 10, + WORKGROUP_OP_EXCLUSIVE_MIN = 11, + WORKGROUP_OP_EXCLUSIVE_MAX = 12, + WORKGROUP_OP_INVALID + }; + /* Vote function per hardware thread */ enum VotePredicate : uint8_t { VOTE_ALL = 0, @@ -576,6 +592,16 @@ namespace ir { static bool isClassOf(const Instruction &insn); }; + /*! Related to Work Group. */ + class WorkGroupInstruction : public Instruction { + public: + /*! Return true if the given instruction is an instance of this class */ + static bool isClassOf(const Instruction &insn); + Type getType(void) const; + WorkGroupOps getWorkGroupOpcode(void) const; + uint32_t getSlmAddr(void) const; + }; + /*! Specialize the instruction. Also performs typechecking first based on the * opcode. Crashes if it fails */ @@ -797,6 +823,8 @@ namespace ir { Instruction CALC_TIMESTAMP(uint32_t pointNum, uint32_t tsType); /*! calculate the execute timestamp for profiling */ Instruction STORE_PROFILING(uint32_t bti, uint32_t Type); + /*! work group */ + Instruction WORKGROUP(WorkGroupOps opcode, uint32_t slmAddr, Register dst, Tuple srcTuple, uint8_t srcNum, Type type); } /* namespace ir */ } /* namespace gbe */ diff --git a/backend/src/ir/instruction.hxx b/backend/src/ir/instruction.hxx index 1282747..e08889d 100644 --- a/backend/src/ir/instruction.hxx +++ b/backend/src/ir/instruction.hxx @@ -109,3 +109,4 @@ DECL_INSN(ELSE, BranchInstruction) DECL_INSN(WHILE, BranchInstruction) DECL_INSN(CALC_TIMESTAMP, CalcTimestampInstruction) DECL_INSN(STORE_PROFILING, StoreProfilingInstruction) +DECL_INSN(WORKGROUP, WorkGroupInstruction) -- 1.7.9.5 _______________________________________________ Beignet mailing list Beignet@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/beignet