[Beignet] [PATCH 4/6] Debug Support: Pass debug infomation to SEL IR
Bai Yannan
yannan.bai at intel.com
Sun Nov 1 18:43:20 PST 2015
1. Add a structure DBGInfo in Opaqueue class, storing debug infomation in selection for subsequentlt passing to selection IR.
2. Add a structure DBGInfo in SelectionInstruction class, storing debug infomation.
3. Pass debug information from GEN IR firstly to selection queue, then pass to selection IR when emitting, if OCL_PROFILING is true.
Signed-off-by: Yannan Bai <yannan.bai at intel.com>
---
backend/src/backend/gen_insn_selection.cpp | 37 ++++++++++++++++++++++++++++++
backend/src/backend/gen_insn_selection.hpp | 6 +++++
2 files changed, 43 insertions(+)
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index fafd927..5961687 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -457,6 +457,8 @@ namespace gbe
bool hasQWord(const ir::Instruction &insn);
/*! A root instruction needs to be generated */
bool isRoot(const ir::Instruction &insn) const;
+ /*! Set debug infomation to Selection */
+ void setDBGInfo_SEL(uint32_t line, uint32_t col) { DBGInfo.line = line; DBGInfo.col = col; }
/*! To handle selection block allocation */
DECL_POOL(SelectionBlock, blockPool);
@@ -494,6 +496,10 @@ namespace gbe
uint32_t vectorNum;
/*! If true, generate code backward */
bool bwdCodeGeneration;
+ struct {
+ uint32_t line;
+ uint32_t col;
+ } DBGInfo;
/*! To make function prototypes more readable */
typedef const GenRegister &Reg;
@@ -862,6 +868,7 @@ namespace gbe
GBE_ASSERT(dstNum <= SelectionInstruction::MAX_DST_NUM && srcNum <= SelectionInstruction::MAX_SRC_NUM);
GBE_ASSERT(this->block != NULL);
SelectionInstruction *insn = this->create(opcode, dstNum, srcNum);
+ insn->setDBGInfo(DBGInfo.line, DBGInfo.col);
if (this->bwdCodeGeneration)
this->bwdList.push_back(insn);
else
@@ -2336,6 +2343,11 @@ namespace gbe
getSrcGenRegImm(dag, dag0, dag1, src0, src1, type, inverse);
}
+extern bool OCL_PROFILING; // first defined by calling BVAR in program.cpp
+#define SET_SEL_DBGINFO(I) \
+ if(OCL_PROFILING) \
+ sel.setDBGInfo_SEL(I.DBGInfo.line, I.DBGInfo.col)
+// end define SET_SEL_DBGINFO
/*! Template for the one-to-many instruction patterns */
template <typename T, typename U>
@@ -2386,6 +2398,7 @@ namespace gbe
const Type type = insn.getType();
GenRegister dst = sel.selReg(insn.getDst(0), type);
+ SET_SEL_DBGINFO(dag.insn);
sel.push();
if (sel.isScalarReg(insn.getDst(0))) {
sel.curr.execWidth = 1;
@@ -2437,6 +2450,7 @@ namespace gbe
const ir::Type insnType = insn.getType();
const GenRegister dst = sel.selReg(insn.getDst(0), getType(opcode, insnType, false));
const GenRegister src = sel.selReg(insn.getSrc(0), getType(opcode, insnType, true));
+ SET_SEL_DBGINFO(insn);
sel.push();
if (sel.isScalarReg(insn.getDst(0)) == true) {
sel.curr.execWidth = 1;
@@ -2699,6 +2713,7 @@ namespace gbe
const Type type = insn.getType();
GenRegister dst = sel.selReg(insn.getDst(0), type);
+ SET_SEL_DBGINFO(dag.insn);
sel.push();
// Boolean values use scalars
@@ -3000,6 +3015,7 @@ namespace gbe
SelectionDAG *child0 = dag.child[0];
SelectionDAG *child1 = dag.child[1];
const GenRegister dst = sel.selReg(insn.getDst(0), TYPE_FLOAT);
+ SET_SEL_DBGINFO(dag.insn);
if (child0 && child0->insn.getOpcode() == OP_MUL) {
GBE_ASSERT(cast<ir::BinaryInstruction>(child0->insn).getType() == TYPE_FLOAT);
SelectionDAG *child00 = child0->child[0];
@@ -3081,6 +3097,7 @@ namespace gbe
sel.getSrcGenRegImm(*cmp, src0, src1, type, inverse);
const uint32_t genCmp = getGenCompare(opcode, inverse);
+ SET_SEL_DBGINFO(dag.insn);
sel.push();
if (sel.isScalarReg(insn.getDst(0)) == true) {
sel.curr.execWidth = 1;
@@ -3122,6 +3139,7 @@ namespace gbe
GenRegister src0 = sel.selReg(insn.getSrc(0), type);
GenRegister src1 = sel.selReg(insn.getSrc(1), type);
+ SET_SEL_DBGINFO(dag.insn);
sel.push();
if (sel.has32X32Mul()) {
if (sel.isScalarReg(insn.getDst(0)) == true) {
@@ -3290,6 +3308,7 @@ namespace gbe
using namespace ir;
const BinaryInstruction &insn = cast<ir::BinaryInstruction>(dag.insn);
const Type type = insn.getType();
+ SET_SEL_DBGINFO(dag.insn);
if (type == TYPE_U32 || type == TYPE_S32) {
if (this->emitMulSpecialReg(sel, dag, 0))
return true;
@@ -3325,6 +3344,7 @@ namespace gbe
const Immediate imm = insn.getImmediate();
const GenRegister dst = sel.selReg(insn.getDst(0), type);
+ SET_SEL_DBGINFO(insn);
sel.push();
if (sel.isScalarReg(insn.getDst(0)) == true) {
sel.curr.execWidth = 1;
@@ -3377,6 +3397,7 @@ namespace gbe
const ir::Register reg = sel.reg(FAMILY_DWORD);
const uint32_t params = insn.getParameters();
+ SET_SEL_DBGINFO(insn);
// A barrier is OK to start the thread synchronization *and* SLM fence
sel.BARRIER(GenRegister::ud8grf(reg), sel.selReg(sel.reg(FAMILY_DWORD)), params);
return true;
@@ -3761,6 +3782,7 @@ namespace gbe
const uint32_t elemSize = getByteScatterGatherSize(sel, type);
bool allConstant = isAllConstant(bti);
+ SET_SEL_DBGINFO(dag.insn);
if (allConstant) {
// XXX TODO read 64bit constant through constant cache
// Per HW Spec, constant cache messages can read at least DWORD data.
@@ -3920,6 +3942,7 @@ namespace gbe
const bool isUniform = sel.isScalarReg(insn.getAddress()) && sel.isScalarReg(insn.getValue(0));
BTI bti = getBTI(dag, insn);
+ SET_SEL_DBGINFO(dag.insn);
if (insn.isAligned() == true && elemSize == GEN_BYTE_SCATTER_QWORD)
this->emitWrite64(sel, insn, address, bti);
else if (insn.isAligned() == true && elemSize == GEN_BYTE_SCATTER_DWORD)
@@ -3959,6 +3982,7 @@ namespace gbe
const ir::Liveness &liveness = sel.ctx.getLiveness();
const ir::Liveness::LiveOut &liveOut = liveness.getLiveOut(curr);
bool needStoreBool = false;
+ SET_SEL_DBGINFO(dag.insn);
if (liveOut.contains(dst) || dag.computeBool)
needStoreBool = true;
@@ -4231,6 +4255,7 @@ namespace gbe
const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
const Opcode opcode = insn.getOpcode();
+ SET_SEL_DBGINFO(insn);
if (opcode == OP_F16TO32) {
sel.F16TO32(dst, src);
@@ -4829,6 +4854,7 @@ namespace gbe
GenAtomicOpCode genAtomicOp = (GenAtomicOpCode)atomicOp;
+ SET_SEL_DBGINFO(dag.insn);
sel.ATOMIC(dst, genAtomicOp, opNum, src0, src1, src2, bti, sel.getBTITemps(b));
// for fixed bti, don't generate the useless loadi
@@ -4869,6 +4895,7 @@ namespace gbe
bool inverse = false;
sel.getSrcGenRegImm(dag, dag1, dag2, src0, src1, type, inverse);
const Register pred = insn.getPredicate();
+ SET_SEL_DBGINFO(dag.insn);
sel.push();
if (sel.isScalarReg(insn.getDst(0)) == true) {
sel.curr.execWidth = 1;
@@ -4909,6 +4936,7 @@ namespace gbe
src0 = sel.selReg(insn.getSrc(0), type),
src1 = sel.selReg(insn.getSrc(1), type),
src2 = sel.selReg(insn.getSrc(2), type);
+ SET_SEL_DBGINFO(insn);
switch(insn.getOpcode()) {
case OP_I64MADSAT:
{
@@ -4960,6 +4988,7 @@ namespace gbe
const GenRegister src1 = sel.getLabelImmReg(label);
const uint32_t simdWidth = sel.ctx.getSimdWidth();
GBE_ASSERTM(label < sel.ctx.getMaxLabel(), "We reached the maximum label number which is reserved for barrier handling");
+ SET_SEL_DBGINFO(insn);
sel.LABEL(label);
if(!insn.getParent()->needIf)
@@ -5100,6 +5129,7 @@ namespace gbe
for (valueID = 0; valueID < insn.getDstNum(); ++valueID)
dst[valueID] = sel.selReg(insn.getDst(valueID), insn.getDstType());
+ SET_SEL_DBGINFO(insn);
if (insn.getSamplerOffset() != 0) {
if(sel.getLdMsgOrder() < LD_MSG_ORDER_SKL)
this->emitLd_ivb(sel, insn, msgPayloads, msgLen);
@@ -5159,6 +5189,7 @@ namespace gbe
msgs[msgID] = sel.selReg(insn.getSrc(valueID), insn.getSrcType());
}
+ SET_SEL_DBGINFO(insn);
sel.push();
sel.curr.predicate = GEN_PREDICATE_NONE;
sel.curr.noMask = 1;
@@ -5223,6 +5254,7 @@ namespace gbe
GenRegister dst;
dst = sel.selReg(insn.getDst(0), TYPE_U32);
GenRegister imageInfoReg = GenRegister::ud1grf(insn.getSrc(0));
+ SET_SEL_DBGINFO(insn);
sel.MOV(dst, imageInfoReg);
return true;
@@ -5252,6 +5284,7 @@ namespace gbe
GenRegister dst;
dst = sel.selReg(insn.getDst(0), insn.getType());
+ SET_SEL_DBGINFO(dag.insn);
sel.push();
sel.curr.predicate = GEN_PREDICATE_NONE;
sel.curr.noMask = 1;
@@ -5294,6 +5327,7 @@ namespace gbe
src1 = sel.selReg(insn.getSrc(1), TYPE_U32);
}
+ SET_SEL_DBGINFO(dag.insn);
sel.push();
if (sel.isScalarReg(insn.getDst(0))) {
sel.curr.execWidth = 1;
@@ -5334,6 +5368,7 @@ namespace gbe
src = GenRegister::ud1grf(insn.getSrc(0));
src = sel.getOffsetReg(src, 0, insn.getOffset()*4);
+ SET_SEL_DBGINFO(dag.insn);
sel.push();
sel.curr.noMask = 1;
sel.curr.predicate = GEN_PREDICATE_NONE;
@@ -5361,6 +5396,7 @@ namespace gbe
src1 = sel.selReg(insn.getSrc(1), TYPE_U32);
GenRegister tmp = sel.selReg(sel.reg(FAMILY_WORD), TYPE_U16);
+ SET_SEL_DBGINFO(dag.insn);
sel.INDIRECT_MOVE(dst, tmp, src0, src1, offset);
markAllChildren(dag);
return true;
@@ -5496,6 +5532,7 @@ namespace gbe
using namespace ir;
const ir::BranchInstruction &insn = cast<BranchInstruction>(dag.insn);
const Opcode opcode = insn.getOpcode();
+ SET_SEL_DBGINFO(dag.insn);
if (opcode == OP_RET)
sel.EOT();
else if (opcode == OP_BRA) {
diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index 4efb80b..79d61a3 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -90,6 +90,8 @@ namespace gbe
const GenRegister &dst(uint32_t dstID) const { return regs[dstID]; }
/*! Damn C++ */
const GenRegister &src(uint32_t srcID) const { return regs[dstNum+srcID]; }
+ /*! Set debug infomation to selection */
+ void setDBGInfo(uint32_t line, uint32_t col) { DBGInfo.line = line; DBGInfo.col = col; }
/*! No more than 9 sources (used by typed writes on simd8 mode.) */
enum { MAX_SRC_NUM = 9 };
/*! No more than 16 destinations (15 used by I64DIV/I64REM) */
@@ -145,6 +147,10 @@ namespace gbe
uint32_t index1;
/*! instruction ID used for vector allocation. */
uint32_t ID;
+ struct {
+ uint32_t line;
+ uint32_t col;
+ } DBGInfo;
/*! Variable sized. Destinations and sources go here */
GenRegister regs[0];
INLINE uint32_t getbti() const {
--
1.9.1
More information about the Beignet
mailing list