[Beignet] [PATCH 2/5 OpenCL-2.0] Add the WorkGroupInstruction as a new type of instruction.
junyan.he at inbox.com
junyan.he at inbox.com
Mon Apr 20 23:11:09 PDT 2015
From: Junyan He <junyan.he at linux.intel.com>
Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
backend/src/ir/instruction.cpp | 158 ++++++++++++++++++++++++++++++++++++++++
backend/src/ir/instruction.hpp | 29 +++++++-
backend/src/ir/instruction.hxx | 1 +
3 files changed, 187 insertions(+), 1 deletion(-)
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp
index 797552f..02498bc 100644
--- a/backend/src/ir/instruction.cpp
+++ b/backend/src/ir/instruction.cpp
@@ -676,6 +676,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];
+ };
+
class ALIGNED_INSTRUCTION ReadARFInstruction :
public BasePolicy,
public NSrcPolicy<ReadARFInstruction, 0>,
@@ -1118,6 +1148,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
/////////////////////////////////////////////////////////////////////////
@@ -1253,7 +1331,76 @@ 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) {
+ int localN = srcNum - 1;
+ GBE_ASSERT(localN);
+ out << " Local X:";
+ out << " %" << this->getSrc(fn, 1);
+ localN--;
+ if (!localN)
+ return;
+
+ out << " Local Y:";
+ out << " %" << this->getSrc(fn, 2);
+ localN--;
+ if (!localN)
+ return;
+ out << " Local Z:";
+ out << " %" << this->getSrc(fn, 3);
+ localN--;
+ GBE_ASSERT(!localN);
+ }
+
+ out << "TheadID Map at SLM: " << this->slmAddr;
+ }
} /* namespace internal */
std::ostream &operator<< (std::ostream &out, AddressSpace addrSpace) {
@@ -1381,6 +1528,10 @@ START_INTROSPECTION(LabelInstruction)
#include "ir/instruction.hxx"
END_INTROSPECTION(LabelInstruction)
+START_INTROSPECTION(WorkGroupInstruction)
+#include "ir/instruction.hxx"
+END_INTROSPECTION(WorkGroupInstruction)
+
#undef END_INTROSPECTION
#undef START_INTROSPECTION
#undef DECL_INSN
@@ -1574,6 +1725,9 @@ DECL_MEM_FN(TypedWriteInstruction, Type, getCoordType(void), getCoordType())
DECL_MEM_FN(TypedWriteInstruction, uint8_t, getImageIndex(void), getImageIndex())
DECL_MEM_FN(GetImageInfoInstruction, uint32_t, getInfoType(void), getInfoType())
DECL_MEM_FN(GetImageInfoInstruction, uint8_t, getImageIndex(void), getImageIndex())
+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
@@ -1792,6 +1946,10 @@ DECL_MEM_FN(GetImageInfoInstruction, uint8_t, getImageIndex(void), getImageIndex
return internal::GetImageInfoInstruction(infoType, dst, imageIndex, infoReg).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 24d27aa..49d5e17 100644
--- a/backend/src/ir/instruction.hpp
+++ b/backend/src/ir/instruction.hpp
@@ -78,6 +78,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,
@@ -512,6 +528,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
*/
@@ -715,7 +741,8 @@ namespace ir {
Instruction GET_IMAGE_INFO(int infoType, Register dst, uint8_t imageIndex, Register infoReg);
/*! label labelIndex */
Instruction LABEL(LabelIndex labelIndex);
-
+ /*! 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 de4abfb..f2ef722 100644
--- a/backend/src/ir/instruction.hxx
+++ b/backend/src/ir/instruction.hxx
@@ -102,3 +102,4 @@ DECL_INSN(IF, BranchInstruction)
DECL_INSN(ENDIF, BranchInstruction)
DECL_INSN(ELSE, BranchInstruction)
DECL_INSN(WHILE, BranchInstruction)
+DECL_INSN(WORKGROUP, WorkGroupInstruction)
--
1.7.9.5
More information about the Beignet
mailing list