diff options
author | Junyan He <junyan.he@linux.intel.com> | 2015-11-18 14:06:44 +0800 |
---|---|---|
committer | Yang Rong <rong.r.yang@intel.com> | 2015-11-25 13:22:11 +0800 |
commit | 7e89f3b8e0506f0d4184a52165971ba7452f65ae (patch) | |
tree | d3e199dd46211ac8d5d50c19db04e227c17d76ec | |
parent | 7840918e23639fee74e745c7fcf4d4ecbcc6c25d (diff) |
Add the WorkGroupInstruction as a new type of instruction.
Signed-off-by: Junyan He <junyan.he@linux.intel.com>
Reviewed-by: Yang Rong <rong.r.yang@intel.com>
-rw-r--r-- | backend/src/ir/instruction.cpp | 161 | ||||
-rw-r--r-- | backend/src/ir/instruction.hpp | 28 | ||||
-rw-r--r-- | backend/src/ir/instruction.hxx | 1 |
3 files changed, 190 insertions, 0 deletions
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp index c7facfbd..734e66b7 100644 --- a/backend/src/ir/instruction.cpp +++ b/backend/src/ir/instruction.cpp @@ -964,6 +964,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 ///////////////////////////////////////////////////////////////////////// @@ -1395,6 +1425,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 ///////////////////////////////////////////////////////////////////////// @@ -1552,6 +1630,78 @@ namespace ir { this->outOpcode(out); } + 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) { @@ -1708,6 +1858,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 @@ -1914,6 +2068,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 @@ -2204,6 +2361,10 @@ DECL_MEM_FN(MemInstruction, void, setBtiReg(Register reg), setBtiReg(reg)) return internal::WaitInstruction().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 76ffd778..9881ff49 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, @@ -582,6 +598,16 @@ namespace ir { /*! Return true if the given instruction is an instance of this class */ 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 @@ -807,6 +833,8 @@ namespace ir { /*! wait */ Instruction WAIT(void); + /*! 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 efdd4c5e..27c71594 100644 --- a/backend/src/ir/instruction.hxx +++ b/backend/src/ir/instruction.hxx @@ -110,3 +110,4 @@ DECL_INSN(WHILE, BranchInstruction) DECL_INSN(CALC_TIMESTAMP, CalcTimestampInstruction) DECL_INSN(STORE_PROFILING, StoreProfilingInstruction) DECL_INSN(WAIT, WaitInstruction) +DECL_INSN(WORKGROUP, WorkGroupInstruction) |