[Beignet] [PATCH] add a debug module
Lv Meng
meng.lv at intel.com
Mon Nov 9 18:29:20 PST 2015
diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt
index f26cc8b..1d109f8 100644
--- a/backend/src/CMakeLists.txt
+++ b/backend/src/CMakeLists.txt
@@ -72,6 +72,8 @@ set (GBE_SRC
ir/immediate.cpp
ir/structurizer.hpp
ir/structurizer.cpp
+ ir/debug.hpp
+ ir/debug.cpp
backend/context.cpp
backend/context.hpp
backend/program.cpp
diff --git a/backend/src/ir/debug.cpp b/backend/src/ir/debug.cpp
new file mode 100644
index 0000000..eec206a
--- /dev/null
+++ b/backend/src/ir/debug.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * \file debug.cpp
+ *
+ */
+#include "ir/debug.hpp"
+
+namespace gbe {
+namespace ir {
+
+ Debug * Debug::instance = NULL;
+ void Debug::dumpDebugInfo(const char *msg, const char *file, const char *fn, int32_t line)
+ {
+ assert(msg != NULL && file != NULL && fn != NULL);
+ fprintf(stderr, "[ ERROR ] Error happened during the build of OpenCL program.\n"
+ "Build error: %s\n"
+ "at driver file %s, function %s, line %i\n"
+ "at source file %s, kernel %s, line %i\n",
+ msg, file, fn, line,
+ filename.c_str(),kernelname.c_str(),srcline);
+
+ fflush(stdout);
+ DEBUGBREAK();
+ exit(-1);
+ }
+} /* namespace ir */
+} /* namespace gbe */
diff --git a/backend/src/ir/debug.hpp b/backend/src/ir/debug.hpp
new file mode 100644
index 0000000..48d7377
--- /dev/null
+++ b/backend/src/ir/debug.hpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * \file debug.hpp
+ *
+ */
+#ifndef __GBE_IR_DEBUG_HPP__
+#define __GBE_IR_DEBUG_HPP__
+
+#include <string.h>
+#include "sys/platform.hpp"
+
+namespace gbe{
+namespace ir{
+ class Debug
+ {
+ public:
+ virtual ~Debug(void){instance = NULL;}
+ static Debug * getDebug(void) {
+ if( instance == NULL )
+ instance = new Debug;
+ return instance;
+ }
+ void dumpDebugInfo(const char *msg, const char *file, const char *fn, int32_t line);
+ protected:
+ Debug(void){srcline = srccol = 0;filename = "stringInput.cl";}
+ public:
+ std::string filename;
+ std::string kernelname;
+ uint32_t srcline;
+ uint32_t srccol;
+ std::string msg;
+ protected:
+ static Debug * instance;
+ GBE_CLASS(Debug);
+ };
+} /* namespac ir */
+
+ #define GBE_DEBUGM(EXPR, MSG) do { \
+ if (UNLIKELY(!(EXPR))) \
+ ir::Debug::getDebug()->dumpDebugInfo(MSG, __FILE__, __FUNCTION__, __LINE__); \
+ } while (0)
+
+} /* namespace gbe */
+
+#endif /* __GBE_IR_DEBUG_HPP__ */
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp
index 0246920..9cafdcc 100644
--- a/backend/src/ir/instruction.cpp
+++ b/backend/src/ir/instruction.cpp
@@ -23,7 +23,7 @@
*/
#include "ir/instruction.hpp"
#include "ir/function.hpp"
-
+#include "ir/debug.hpp"
namespace gbe {
namespace ir {
@@ -60,11 +60,11 @@ namespace ir {
struct NSrcPolicy {
INLINE uint32_t getSrcNum(void) const { return srcNum; }
INLINE Register getSrc(const Function &fn, uint32_t ID) const {
- GBE_ASSERTM((int) ID < (int) srcNum, "Out-of-bound source");
+ GBE_DEBUGM((int) ID < (int) srcNum, "Out-of-bound source");
return static_cast<const T*>(this)->src[ID];
}
INLINE void setSrc(Function &fn, uint32_t ID, Register reg) {
- GBE_ASSERTM((int) ID < (int) srcNum, "Out-of-bound source");
+ GBE_DEBUGM((int) ID < (int) srcNum, "Out-of-bound source");
static_cast<T*>(this)->src[ID] = reg;
}
};
@@ -74,11 +74,11 @@ namespace ir {
struct NDstPolicy {
INLINE uint32_t getDstNum(void) const { return dstNum; }
INLINE Register getDst(const Function &fn, uint32_t ID) const {
- GBE_ASSERTM((int) ID < (int) dstNum, "Out-of-bound destination");
+ GBE_DEBUGM((int) ID < (int) dstNum, "Out-of-bound destination");
return static_cast<const T*>(this)->dst[ID];
}
INLINE void setDst(Function &fn, uint32_t ID, Register reg) {
- GBE_ASSERTM((int) ID < (int) dstNum, "Out-of-bound destination");
+ GBE_DEBUGM((int) ID < (int) dstNum, "Out-of-bound destination");
static_cast<T*>(this)->dst[ID] = reg;
}
};
@@ -90,11 +90,11 @@ namespace ir {
return static_cast<const T*>(this)->srcNum;
}
INLINE Register getSrc(const Function &fn, uint32_t ID) const {
- GBE_ASSERTM(ID < static_cast<const T*>(this)->srcNum, "Out-of-bound source register");
+ GBE_DEBUGM(ID < static_cast<const T*>(this)->srcNum, "Out-of-bound source register");
return fn.getRegister(static_cast<const T*>(this)->src, ID);
}
INLINE void setSrc(Function &fn, uint32_t ID, Register reg) {
- GBE_ASSERTM(ID < static_cast<const T*>(this)->srcNum, "Out-of-bound source register");
+ GBE_DEBUGM(ID < static_cast<const T*>(this)->srcNum, "Out-of-bound source register");
return fn.setRegister(static_cast<T*>(this)->src, ID, reg);
}
};
@@ -106,11 +106,11 @@ namespace ir {
return static_cast<const T*>(this)->dstNum;
}
INLINE Register getDst(const Function &fn, uint32_t ID) const {
- GBE_ASSERTM(ID < static_cast<const T*>(this)->dstNum, "Out-of-bound source register");
+ GBE_DEBUGM(ID < static_cast<const T*>(this)->dstNum, "Out-of-bound source register");
return fn.getRegister(static_cast<const T*>(this)->dst, ID);
}
INLINE void setDst(Function &fn, uint32_t ID, Register reg) {
- GBE_ASSERTM(ID < static_cast<const T*>(this)->dstNum, "Out-of-bound source register");
+ GBE_DEBUGM(ID < static_cast<const T*>(this)->dstNum, "Out-of-bound source register");
return fn.setRegister(static_cast<T*>(this)->dst, ID, reg);
}
};
@@ -388,7 +388,7 @@ namespace ir {
srcNum = payloadNum + getBaseSrcNum();
}
INLINE Register getSrc(const Function &fn, uint32_t ID) const {
- GBE_ASSERTM((int)ID < (int)srcNum, "Out-of-bound source register for atomic");
+ GBE_DEBUGM((int)ID < (int)srcNum, "Out-of-bound source register for atomic");
if (ID == 0) {
return offset;
} else if (hasExtraBtiReg() && (int)ID == (int)srcNum-1) {
@@ -398,7 +398,7 @@ namespace ir {
}
}
INLINE void setSrc(Function &fn, uint32_t ID, Register reg) {
- GBE_ASSERTM((int)ID < (int)srcNum, "Out-of-bound source register for atomic");
+ GBE_DEBUGM((int)ID < (int)srcNum, "Out-of-bound source register for atomic");
if (ID == 0) {
offset = reg;
} else if (hasExtraBtiReg() && (int)ID == (int)srcNum - 1) {
@@ -446,18 +446,18 @@ namespace ir {
this->hasLabel = false;
}
INLINE LabelIndex getLabelIndex(void) const {
- GBE_ASSERTM(hasLabel, "No target label for this branch instruction");
+ GBE_DEBUGM(hasLabel, "No target label for this branch instruction");
return labelIndex;
}
INLINE uint32_t getSrcNum(void) const { return hasPredicate ? 1 : 0; }
INLINE Register getSrc(const Function &fn, uint32_t ID) const {
- GBE_ASSERTM(hasPredicate, "No source for unpredicated branches");
- GBE_ASSERTM(ID == 0, "Only one source for the branch instruction");
+ GBE_DEBUGM(hasPredicate, "No source for unpredicated branches");
+ GBE_DEBUGM(ID == 0, "Only one source for the branch instruction");
return predicate;
}
INLINE void setSrc(Function &fn, uint32_t ID, Register reg) {
- GBE_ASSERTM(hasPredicate, "No source for unpredicated branches");
- GBE_ASSERTM(ID == 0, "Only one source for the branch instruction");
+ GBE_DEBUGM(hasPredicate, "No source for unpredicated branches");
+ GBE_DEBUGM(ID == 0, "Only one source for the branch instruction");
predicate = reg;
}
INLINE bool isPredicated(void) const { return hasPredicate; }
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 39665b8..2335727 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -79,6 +79,7 @@
#include "ir/half.hpp"
#include "ir/liveness.hpp"
#include "ir/value.hpp"
+#include "ir/debug.hpp"
#include "sys/set.hpp"
#include "sys/cvar.hpp"
#include "backend/program.h"
@@ -231,7 +232,7 @@ namespace gbe
GBE_ASSERT(CV != NULL);
#if GBE_DEBUG
const uint32_t elemNum = CV->getNumOperands();
- GBE_ASSERTM(index < elemNum, "Out-of-bound constant vector access");
+ GBE_DEBUGM(index < elemNum, "Out-of-bound constant vector access");
#endif /* GBE_DEBUG */
CPV = cast<Constant>(CV->getOperand(index));
return CPV;
@@ -299,7 +300,7 @@ namespace gbe
elementTypeID != Type::FloatTyID &&
elementTypeID != Type::HalfTyID &&
elementTypeID != Type::DoubleTyID)
- GBE_ASSERTM(false, "Vectors of elements are not supported");
+ GBE_DEBUGM(false, "Vectors of elements are not supported");
return this->_newScalar(value, key, elementType, index, uniform);
break;
}
@@ -312,7 +313,7 @@ namespace gbe
elementTypeID != Type::FloatTyID &&
elementTypeID != Type::HalfTyID &&
elementTypeID != Type::DoubleTyID)
- GBE_ASSERTM(false, "Strcuts of elements are not supported");
+ GBE_DEBUGM(false, "Strcuts of elements are not supported");
return this->_newScalar(value, key, elementType, index, uniform);
break;
}
@@ -1529,7 +1530,7 @@ namespace gbe
} else if (Ty == Type::getDoubleTy(CPV->getContext())) {
return processSeqConstant<double>(seq, index, CONST_DOUBLE);
} else if (Ty == Type::getHalfTy(CPV->getContext())) {
- GBE_ASSERTM(0, "Const data array never be half float\n");
+ GBE_DEBUGM(0, "Const data array never be half float\n");
}
} else
#endif /* LLVM_VERSION_MINOR > 0 */
@@ -1563,13 +1564,13 @@ namespace gbe
const double f64 = 0;
return ctx.newImmediate(f64);
} else {
- GBE_ASSERTM(false, "Unsupporte aggregate zero type.");
+ GBE_DEBUGM(false, "Unsupporte aggregate zero type.");
return ctx.newImmediate(uint32_t(0));
}
} else {
if (dyn_cast<ConstantVector>(CPV))
return processConstantVector(dyn_cast<ConstantVector>(CPV), index);
- GBE_ASSERTM(dyn_cast<ConstantExpr>(CPV) == NULL, "Unsupported constant expression");
+ GBE_DEBUGM(dyn_cast<ConstantExpr>(CPV) == NULL, "Unsupported constant expression");
// Integers
if (ConstantInt *CI = dyn_cast<ConstantInt>(CPV)) {
@@ -1643,12 +1644,12 @@ namespace gbe
}
break;
default:
- GBE_ASSERTM(false, "Unsupported constant type");
+ GBE_DEBUGM(false, "Unsupported constant type");
break;
}
}
- GBE_ASSERTM(false, "Unsupported constant type");
+ GBE_DEBUGM(false, "Unsupported constant type");
return ctx.newImmediate(uint64_t(0));
}
@@ -1850,7 +1851,7 @@ namespace gbe
void GenWriter::emitFunctionPrototype(Function &F)
{
- GBE_ASSERTM(F.hasStructRetAttr() == false,
+ GBE_DEBUGM(F.hasStructRetAttr() == false,
"Returned value for kernel functions is forbidden");
// Loop over the kernel metadatas to set the required work group size.
@@ -2003,7 +2004,7 @@ namespace gbe
continue;
}
- GBE_ASSERTM(isScalarType(type) == true,
+ GBE_DEBUGM(isScalarType(type) == true,
"vector type in the function argument is not supported yet");
const ir::Register reg = getRegister(I);
if (llvmInfo.isImageType()) {
@@ -2061,7 +2062,7 @@ namespace gbe
// structure
#if GBE_DEBUG
const Type *type = F.getReturnType();
- GBE_ASSERTM(type->isVoidTy() == true,
+ GBE_DEBUGM(type->isVoidTy() == true,
"Returned value for kernel functions is forbidden");
// Variable number of arguments is not supported
@@ -2793,7 +2794,7 @@ namespace gbe
#endif
break;
default:
- GBE_ASSERTM(false, "Unsupported calling convention");
+ GBE_DEBUGM(false, "Unsupported calling convention");
}
ctx.startFunction(F.getName());
@@ -2846,7 +2847,7 @@ namespace gbe
void GenWriter::emitReturnInst(ReturnInst &I) {
const ir::Function &fn = ctx.getFunction();
- GBE_ASSERTM(fn.outputNum() <= 1, "no more than one value can be returned");
+ GBE_DEBUGM(fn.outputNum() <= 1, "no more than one value can be returned");
if (fn.outputNum() == 1 && I.getNumOperands() > 0) {
const ir::Register dst = fn.getOutput(0);
const ir::Register src = this->getRegister(I.getOperand(0));
@@ -3398,7 +3399,7 @@ namespace gbe
this->newRegister(&I);
break;
default:
- GBE_ASSERTM(false, "Unsupported intrinsics");
+ GBE_DEBUGM(false, "Unsupported intrinsics");
}
return;
}
@@ -3667,7 +3668,7 @@ namespace gbe
// This is not a kernel argument sampler, we need to append it to sampler set,
// and allocate a sampler slot for it.
const ir::Immediate &x = processConstantImm(CPV);
- GBE_ASSERTM(x.getType() == ir::TYPE_U32 || x.getType() == ir::TYPE_S32, "Invalid sampler type");
+ GBE_DEBUGM(x.getType() == ir::TYPE_U32 || x.getType() == ir::TYPE_S32, "Invalid sampler type");
index = ctx.getFunction().getSamplerSet()->append(x.getIntegerValue(), &ctx);
} else {
@@ -3970,7 +3971,7 @@ namespace gbe
Constant *CPV = dyn_cast<Constant>(samplerOffsetVal);
assert(CPV);
const ir::Immediate &x = processConstantImm(CPV);
- GBE_ASSERTM(x.getType() == ir::TYPE_U32 || x.getType() == ir::TYPE_S32, "Invalid sampler type");
+ GBE_DEBUGM(x.getType() == ir::TYPE_U32 || x.getType() == ir::TYPE_S32, "Invalid sampler type");
samplerOffset = x.getIntegerValue();
#endif
bool isFloatCoord = coordType == ir::TYPE_FLOAT;
@@ -4549,7 +4550,7 @@ namespace gbe
// We follow OCL spec and support 2,3,4,8,16 elements only
uint32_t elemNum = vectorType->getNumElements();
- GBE_ASSERTM(elemNum == 2 || elemNum == 3 || elemNum == 4 || elemNum == 8 || elemNum == 16,
+ GBE_DEBUGM(elemNum == 2 || elemNum == 3 || elemNum == 4 || elemNum == 8 || elemNum == 16,
"Only vectors of 2,3,4,8 or 16 elements are supported");
// Per OPenCL 1.2 spec 6.1.5:
// For 3-component vector data types, the size of the data type is 4 * sizeof(component).
diff --git a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp
index 24d4be7..7e96fd6 100644
--- a/backend/src/llvm/llvm_to_gen.cpp
+++ b/backend/src/llvm/llvm_to_gen.cpp
@@ -31,7 +31,7 @@
#include "ir/unit.hpp"
#include "ir/function.hpp"
#include "ir/structurizer.hpp"
-
+#include "ir/debug.hpp"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -217,6 +217,7 @@ namespace gbe
llvm::SMDiagnostic Err;
Module* cl_mod = NULL;
+ ir::Debug *debug = ir::Debug::getDebug();
if (module) {
cl_mod = reinterpret_cast<Module*>(const_cast<void*>(module));
} else if (fileName){
@@ -310,7 +311,7 @@ namespace gbe
iter++;
}
-
+ delete debug;
delete libraryInfo;
return true;
}
--
1.9.1
More information about the Beignet
mailing list