[Beignet] [PATCH 2/4 opencl 1.2] Add the llvm info to the function for later usage.
junyan.he at inbox.com
junyan.he at inbox.com
Sun Jun 8 23:38:52 PDT 2014
From: Junyan He <junyan.he at linux.intel.com>
Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
backend/src/backend/context.cpp | 1 +
backend/src/ir/context.cpp | 5 +-
backend/src/ir/context.hpp | 3 +-
backend/src/ir/function.hpp | 15 +++++-
backend/src/llvm/llvm_gen_backend.cpp | 86 ++++++++++++++++++++++++-----------
5 files changed, 78 insertions(+), 32 deletions(-)
diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp
index db968c3..5dff573 100644
--- a/backend/src/backend/context.cpp
+++ b/backend/src/backend/context.cpp
@@ -468,6 +468,7 @@ namespace gbe
const auto &arg = fn.getArg(argID);
kernel->args[argID].align = arg.align;
+ kernel->args[argID].info = arg.info;
switch (arg.type) {
case ir::FunctionArgument::VALUE:
case ir::FunctionArgument::STRUCTURE:
diff --git a/backend/src/ir/context.cpp b/backend/src/ir/context.cpp
index 256002b..bfbe825 100644
--- a/backend/src/ir/context.cpp
+++ b/backend/src/ir/context.cpp
@@ -107,10 +107,11 @@ namespace ir {
return index;
}
- void Context::input(const std::string &name, FunctionArgument::Type type, Register reg, uint32_t elementSize, uint32_t align) {
+ void Context::input(const std::string &name, FunctionArgument::Type type, Register reg,
+ FunctionArgument::InfoFromLLVM& info, uint32_t elementSize, uint32_t align) {
GBE_ASSERTM(fn != NULL, "No function currently defined");
GBE_ASSERTM(reg < fn->file.regNum(), "Out-of-bound register");
- FunctionArgument *arg = GBE_NEW(FunctionArgument, type, reg, elementSize, name, align);
+ FunctionArgument *arg = GBE_NEW(FunctionArgument, type, reg, elementSize, name, align, info);
fn->args.push_back(arg);
}
diff --git a/backend/src/ir/context.hpp b/backend/src/ir/context.hpp
index ae5783a..27ff4e9 100644
--- a/backend/src/ir/context.hpp
+++ b/backend/src/ir/context.hpp
@@ -109,7 +109,8 @@ namespace ir {
/*! Create a new label for the current function */
LabelIndex label(void);
/*! Append a new input register for the function */
- void input(const std::string &name, FunctionArgument::Type type, Register reg, uint32_t elemSz = 0u, uint32_t align = 0);
+ void input(const std::string &name, FunctionArgument::Type type, Register reg,
+ FunctionArgument::InfoFromLLVM& info, uint32_t elemSz = 0u, uint32_t align = 0);
/*! Append a new output register for the function */
void output(Register reg);
/*! Get the immediate value */
diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp
index 266e652..a59fbec 100644
--- a/backend/src/ir/function.hpp
+++ b/backend/src/ir/function.hpp
@@ -107,14 +107,25 @@ namespace ir {
IMAGE = 5, // image*d_t
SAMPLER = 6
};
+
+ struct InfoFromLLVM { // All the info about passed by llvm, using -cl-kernel-arg-info
+ uint32_t addrSpace;
+ std::string typeName;
+ std::string accessQual;
+ std::string typeQual;
+ std::string argName; // My different from arg->getName()
+ };
+
/*! Create a function input argument */
- INLINE FunctionArgument(Type type, Register reg, uint32_t size, const std::string &name, uint32_t align) :
- type(type), reg(reg), size(size), align(align), name(name) {}
+ INLINE FunctionArgument(Type type, Register reg, uint32_t size, const std::string &name, uint32_t align, InfoFromLLVM& info) :
+ type(type), reg(reg), size(size), align(align), name(name), info(info) { }
+
Type type; //!< Gives the type of argument we have
Register reg; //!< Holds the argument
uint32_t size; //!< == sizeof(void*) for ptr, sizeof(elem) for the rest
uint32_t align; //!< address alignment for the argument
const std::string name; //!< Holds the function name for IR output
+ InfoFromLLVM info; //!< Holds the llvm passed info
GBE_STRUCT(FunctionArgument); // Use custom allocator
};
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index e8fa673..71be380 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1096,28 +1096,54 @@ namespace gbe
// Loop over the kernel metadatas to set the required work group size.
NamedMDNode *clKernelMetaDatas = TheModule->getNamedMetadata("opencl.kernels");
size_t reqd_wg_sz[3] = {0, 0, 0};
- for(uint i = 0; i < clKernelMetaDatas->getNumOperands(); i++)
- {
- MDNode *node = clKernelMetaDatas->getOperand(i);
- if (node->getOperand(0) != &F) continue;
- for(uint j = 0; j < node->getNumOperands() - 1; j++)
- {
- MDNode *attrNode = dyn_cast_or_null<MDNode>(node->getOperand(1 + j));
- if (attrNode == NULL) break;
- MDString *attrName = dyn_cast_or_null<MDString>(attrNode->getOperand(0));
- if (attrName && attrName->getString() == "reqd_work_group_size") {
- GBE_ASSERT(attrNode->getNumOperands() == 4);
- ConstantInt *x = dyn_cast<ConstantInt>(attrNode->getOperand(1));
- ConstantInt *y = dyn_cast<ConstantInt>(attrNode->getOperand(2));
- ConstantInt *z = dyn_cast<ConstantInt>(attrNode->getOperand(3));
- GBE_ASSERT(x && y && z);
- reqd_wg_sz[0] = x->getZExtValue();
- reqd_wg_sz[1] = y->getZExtValue();
- reqd_wg_sz[2] = z->getZExtValue();
- break;
- }
+ ir::FunctionArgument::InfoFromLLVM llvmInfo;
+ MDNode *node = NULL;
+ MDNode *addrSpaceNode = NULL;
+ MDNode *typeNameNode = NULL;
+ MDNode *accessQualNode = NULL;
+ MDNode *typeQualNode = NULL;
+ MDNode *argNameNode = NULL;
+
+ /* First find the meta data belong to this function. */
+ for(uint i = 0; i < clKernelMetaDatas->getNumOperands(); i++) {
+ node = clKernelMetaDatas->getOperand(i);
+ if (node->getOperand(0) == &F) break;
+ node = NULL;
+ }
+
+ /* because "-cl-kernel-arg-info", should always have meta data. */
+ if (!F.arg_empty())
+ assert(node);
+
+ for(uint j = 0; j < node->getNumOperands() - 1; j++) {
+ MDNode *attrNode = dyn_cast_or_null<MDNode>(node->getOperand(1 + j));
+ if (attrNode == NULL) break;
+ MDString *attrName = dyn_cast_or_null<MDString>(attrNode->getOperand(0));
+ if (!attrName) continue;
+
+ if (attrName->getString() == "reqd_work_group_size") {
+ GBE_ASSERT(attrNode->getNumOperands() == 4);
+ ConstantInt *x = dyn_cast<ConstantInt>(attrNode->getOperand(1));
+ ConstantInt *y = dyn_cast<ConstantInt>(attrNode->getOperand(2));
+ ConstantInt *z = dyn_cast<ConstantInt>(attrNode->getOperand(3));
+ GBE_ASSERT(x && y && z);
+ reqd_wg_sz[0] = x->getZExtValue();
+ reqd_wg_sz[1] = y->getZExtValue();
+ reqd_wg_sz[2] = z->getZExtValue();
+ break;
+ } else if (attrName->getString() == "kernel_arg_addr_space") {
+ addrSpaceNode = attrNode;
+ } else if (attrName->getString() == "kernel_arg_access_qual") {
+ accessQualNode = attrNode;
+ } else if (attrName->getString() == "kernel_arg_type") {
+ typeNameNode = attrNode;
+ } else if (attrName->getString() == "kernel_arg_type_qual") {
+ typeQualNode = attrNode;
+ } else if (attrName->getString() == "kernel_arg_name") {
+ argNameNode = attrNode;
}
}
+
ctx.getFunction().setCompileWorkGroupSize(reqd_wg_sz[0], reqd_wg_sz[1], reqd_wg_sz[2]);
// Loop over the arguments and output registers for them
if (!F.arg_empty()) {
@@ -1132,6 +1158,12 @@ namespace gbe
const std::string &argName = I->getName().str();
Type *type = I->getType();
+ llvmInfo.addrSpace = (cast<ConstantInt>(addrSpaceNode->getOperand(1 + argID)))->getZExtValue();
+ llvmInfo.typeName = (cast<MDString>(typeNameNode->getOperand(1 + argID)))->getString();
+ llvmInfo.accessQual = (cast<MDString>(accessQualNode->getOperand(1 + argID)))->getString();
+ llvmInfo.typeQual = (cast<MDString>(typeQualNode->getOperand(1 + argID)))->getString();
+ llvmInfo.argName = (cast<MDString>(argNameNode->getOperand(1 + argID)))->getString();
+
// function arguments are uniform values.
this->newRegister(I, NULL, true);
// add support for vector argument.
@@ -1142,7 +1174,7 @@ namespace gbe
const uint32_t elemSize = getTypeByteSize(unit, elemType);
const uint32_t elemNum = vectorType->getNumElements();
//vector's elemType always scalar type
- ctx.input(argName, ir::FunctionArgument::VALUE, reg, elemNum*elemSize, getAlignmentByte(unit, type));
+ ctx.input(argName, ir::FunctionArgument::VALUE, reg, llvmInfo, elemNum*elemSize, getAlignmentByte(unit, type));
ir::Function& fn = ctx.getFunction();
for(uint32_t i=1; i < elemNum; i++) {
@@ -1157,7 +1189,7 @@ namespace gbe
"vector type in the function argument is not supported yet");
const ir::Register reg = getRegister(I);
if (type->isPointerTy() == false)
- ctx.input(argName, ir::FunctionArgument::VALUE, reg, getTypeByteSize(unit, type), getAlignmentByte(unit, type));
+ ctx.input(argName, ir::FunctionArgument::VALUE, reg, llvmInfo, getTypeByteSize(unit, type), getAlignmentByte(unit, type));
else {
PointerType *pointerType = dyn_cast<PointerType>(type);
Type *pointed = pointerType->getElementType();
@@ -1168,7 +1200,7 @@ namespace gbe
if (I->hasByValAttr()) {
#endif /* LLVM_VERSION_MINOR <= 1 */
const size_t structSize = getTypeByteSize(unit, pointed);
- ctx.input(argName, ir::FunctionArgument::STRUCTURE, reg, structSize, getAlignmentByte(unit, type));
+ ctx.input(argName, ir::FunctionArgument::STRUCTURE, reg, llvmInfo, structSize, getAlignmentByte(unit, type));
}
// Regular user provided pointer (global, local or constant)
else {
@@ -1178,17 +1210,17 @@ namespace gbe
const uint32_t align = getAlignmentByte(unit, pointed);
switch (addrSpace) {
case ir::MEM_GLOBAL:
- ctx.input(argName, ir::FunctionArgument::GLOBAL_POINTER, reg, ptrSize, align);
+ ctx.input(argName, ir::FunctionArgument::GLOBAL_POINTER, reg, llvmInfo, ptrSize, align);
break;
case ir::MEM_LOCAL:
- ctx.input(argName, ir::FunctionArgument::LOCAL_POINTER, reg, ptrSize, align);
+ ctx.input(argName, ir::FunctionArgument::LOCAL_POINTER, reg, llvmInfo, ptrSize, align);
ctx.getFunction().setUseSLM(true);
break;
case ir::MEM_CONSTANT:
- ctx.input(argName, ir::FunctionArgument::CONSTANT_POINTER, reg, ptrSize, align);
+ ctx.input(argName, ir::FunctionArgument::CONSTANT_POINTER, reg, llvmInfo, ptrSize, align);
break;
case ir::IMAGE:
- ctx.input(argName, ir::FunctionArgument::IMAGE, reg, ptrSize, align);
+ ctx.input(argName, ir::FunctionArgument::IMAGE, reg, llvmInfo, ptrSize, align);
ctx.getFunction().getImageSet()->append(reg, &ctx);
break;
default: GBE_ASSERT(addrSpace != ir::MEM_PRIVATE);
--
1.8.3.2
More information about the Beignet
mailing list